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