137b74a387bb3993387029859c2d9d051c41c724eStephen Hines//===- DebugString.cpp ----------------------------------------------------===//
237b74a387bb3993387029859c2d9d051c41c724eStephen Hines//
337b74a387bb3993387029859c2d9d051c41c724eStephen Hines//                     The MCLinker Project
437b74a387bb3993387029859c2d9d051c41c724eStephen Hines//
537b74a387bb3993387029859c2d9d051c41c724eStephen Hines// This file is distributed under the University of Illinois Open Source
637b74a387bb3993387029859c2d9d051c41c724eStephen Hines// License. See LICENSE.TXT for details.
737b74a387bb3993387029859c2d9d051c41c724eStephen Hines//
837b74a387bb3993387029859c2d9d051c41c724eStephen Hines//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/DebugString.h"
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSection.h"
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSymbol.h"
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/RelocData.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ResolveInfo.h"
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/SectionData.h"
1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/Fragment.h"
1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/RegionFragment.h"
1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/Relocation.h"
1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/TargetLDBackend.h"
1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/Relocator.h"
2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
2137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <llvm/Support/Casting.h>
2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <llvm/Support/ManagedStatic.h>
2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines
2437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
2537b74a387bb3993387029859c2d9d051c41c724eStephen Hines
2637b74a387bb3993387029859c2d9d051c41c724eStephen Hines// DebugString represents the output .debug_str section, which is at most on
2737b74a387bb3993387029859c2d9d051c41c724eStephen Hines// in each linking
2837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic llvm::ManagedStatic<DebugString> g_DebugString;
2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines
3037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic inline size_t string_length(const char* pStr) {
3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  const char* p = pStr;
3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  size_t len = 0;
3337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  for (; *p != 0; ++p)
3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ++len;
3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  return len;
3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines}
3737b74a387bb3993387029859c2d9d051c41c724eStephen Hines
3837b74a387bb3993387029859c2d9d051c41c724eStephen Hines//==========================
3937b74a387bb3993387029859c2d9d051c41c724eStephen Hines// DebugString
4037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid DebugString::merge(LDSection& pSection) {
4137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  // get the fragment contents
4237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  llvm::StringRef strings;
4337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  SectionData::iterator it, end = pSection.getSectionData()->end();
4437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  for (it = pSection.getSectionData()->begin(); it != end; ++it) {
4537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    if ((*it).getKind() == Fragment::Region) {
4637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      RegionFragment* frag = llvm::cast<RegionFragment>(&(*it));
4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      strings = frag->getRegion().data();
4837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    }
4937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }
5037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
5137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  // get the debug strings and add them into merged string table
5237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  const char* str = strings.data();
5337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  const char* str_end = str + pSection.size();
5437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  while (str < str_end) {
5537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    size_t len = string_length(str);
5637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    m_StringTable.insertString(llvm::StringRef(str, len));
5737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    str = str + len + 1;
5837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }
5937b74a387bb3993387029859c2d9d051c41c724eStephen Hines}
6037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
6137b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t DebugString::computeOffsetSize() {
6237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  size_t size = m_StringTable.finalizeOffset();
6337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  m_pSection->setSize(size);
6437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  return size;
6537b74a387bb3993387029859c2d9d051c41c724eStephen Hines}
6637b74a387bb3993387029859c2d9d051c41c724eStephen Hines
6737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid DebugString::applyOffset(Relocation& pReloc, TargetLDBackend& pBackend) {
6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  // get the refered string
6937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  ResolveInfo* info = pReloc.symInfo();
7037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  // the symbol should point to the first region fragment in the debug
7137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  // string section, get the input .debut_str region
7237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  llvm::StringRef d_str;
7337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (info->outSymbol()->fragRef()->frag()->getKind() == Fragment::Region) {
7437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    RegionFragment* frag =
7537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        llvm::cast<RegionFragment>(info->outSymbol()->fragRef()->frag());
7637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    d_str = frag->getRegion();
7737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }
7837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  uint32_t offset = pBackend.getRelocator()->getDebugStringOffset(pReloc);
7937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  const char* str = d_str.data() + offset;
8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
8137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  // apply the relocation
8237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  pBackend.getRelocator()->applyDebugStringOffset(pReloc,
8337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_StringTable.getOutputOffset(llvm::StringRef(str, string_length(str))));
8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines}
8537b74a387bb3993387029859c2d9d051c41c724eStephen Hines
8637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid DebugString::emit(MemoryRegion& pRegion) {
8737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  return m_StringTable.emit(pRegion);
8837b74a387bb3993387029859c2d9d051c41c724eStephen Hines}
8937b74a387bb3993387029859c2d9d051c41c724eStephen Hines
9037b74a387bb3993387029859c2d9d051c41c724eStephen HinesDebugString* DebugString::Create(LDSection& pSection) {
9137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  g_DebugString->setOutputSection(pSection);
9237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  return &(*g_DebugString);
9337b74a387bb3993387029859c2d9d051c41c724eStephen Hines}
9437b74a387bb3993387029859c2d9d051c41c724eStephen Hines
9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
96