16f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===- ELFReader.cpp ------------------------------------------------------===//
26f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//
36f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//                     The MCLinker Project
46f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//
56f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// This file is distributed under the University of Illinois Open Source
66f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// License. See LICENSE.TXT for details.
76f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//
86f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFReaderIf.h"
106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/IRBuilder.h"
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/FillFragment.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/EhFrame.h"
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDContext.h"
1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/SectionData.h"
1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNULDBackend.h"
176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/ADT/StringRef.h>
196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/ADT/Twine.h>
206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/ELF.h>
216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/Host.h>
226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <cstring>
2437b74a387bb3993387029859c2d9d051c41c724eStephen Hines
2537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===//
286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// ELFReaderIF
296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===//
306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymType
3137b74a387bb3993387029859c2d9d051c41c724eStephen HinesResolveInfo::Type ELFReaderIF::getSymType(uint8_t pInfo,
3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                          uint16_t pShndx) const {
336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo::Type result = static_cast<ResolveInfo::Type>(pInfo & 0xF);
3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (pShndx == llvm::ELF::SHN_ABS && result == ResolveInfo::Section) {
356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // In Mips, __gp_disp is a special section symbol. Its name comes from
366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // .strtab, not .shstrtab. However, it is unique. Only it is also a ABS
376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // symbol. So here is a tricky to identify __gp_disp and convert it to
386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // Object symbol.
396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return ResolveInfo::Object;
406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return result;
436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymDesc
4637b74a387bb3993387029859c2d9d051c41c724eStephen HinesResolveInfo::Desc ELFReaderIF::getSymDesc(uint16_t pShndx,
4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                          const Input& pInput) const {
486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pShndx == llvm::ELF::SHN_UNDEF)
496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return ResolveInfo::Undefined;
506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pShndx < llvm::ELF::SHN_LORESERVE) {
526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // an ELF symbol defined in a section which we are not including
536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // must be treated as an Undefined.
5437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    if (pInput.context()->getSection(pShndx) == NULL ||
556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        LDFileFormat::Ignore == pInput.context()->getSection(pShndx)->kind())
566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return ResolveInfo::Undefined;
576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return ResolveInfo::Define;
586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pShndx == llvm::ELF::SHN_ABS)
616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return ResolveInfo::Define;
626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pShndx == llvm::ELF::SHN_COMMON)
646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return ResolveInfo::Common;
656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (pShndx >= llvm::ELF::SHN_LOPROC && pShndx <= llvm::ELF::SHN_HIPROC)
676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return target().getSymDesc(pShndx);
686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // FIXME: ELF weak alias should be ResolveInfo::Indirect
706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return ResolveInfo::NoneDesc;
716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymBinding
7437b74a387bb3993387029859c2d9d051c41c724eStephen HinesResolveInfo::Binding ELFReaderIF::getSymBinding(uint8_t pBinding,
7537b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                                uint16_t pShndx,
7637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                                uint8_t pVis) const {
776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // TODO:
786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // if --just-symbols option is enabled, the symbol must covert to Absolute
796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  switch (pBinding) {
8137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::STB_LOCAL:
8237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      return ResolveInfo::Local;
8337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::STB_GLOBAL:
8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (pShndx == llvm::ELF::SHN_ABS)
8537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        return ResolveInfo::Absolute;
8637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      return ResolveInfo::Global;
8737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::STB_WEAK:
8837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      return ResolveInfo::Weak;
896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return ResolveInfo::NoneBinding;
926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymFragmentRef
9537b74a387bb3993387029859c2d9d051c41c724eStephen HinesFragmentRef* ELFReaderIF::getSymFragmentRef(Input& pInput,
9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                            uint16_t pShndx,
9737b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                            uint32_t pOffset) const {
9837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (pInput.type() == Input::DynObj)
996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return FragmentRef::Null();
1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pShndx == llvm::ELF::SHN_UNDEF)
1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return FragmentRef::Null();
1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
10437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (pShndx >= llvm::ELF::SHN_LORESERVE)  // including ABS and COMMON
1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return FragmentRef::Null();
1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  LDSection* sect_hdr = pInput.context()->getSection(pShndx);
1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
10937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (sect_hdr == NULL)
11037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    unreachable(diag::unreachable_invalid_section_idx)
11137b74a387bb3993387029859c2d9d051c41c724eStephen Hines        << pShndx << pInput.path().native();
1126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (sect_hdr->kind() == LDFileFormat::Ignore)
1146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return FragmentRef::Null();
1156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (sect_hdr->kind() == LDFileFormat::Group)
1176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return FragmentRef::Null();
1186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return FragmentRef::Create(*sect_hdr, pOffset);
1206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymVisibility
12337b74a387bb3993387029859c2d9d051c41c724eStephen HinesResolveInfo::Visibility ELFReaderIF::getSymVisibility(uint8_t pVis) const {
1246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return static_cast<ResolveInfo::Visibility>(pVis);
1256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
1266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymValue - get the section offset of the symbol.
1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFReaderIF::getSymValue(uint64_t pValue,
1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                  uint16_t pShndx,
13037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  const Input& pInput) const {
13137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (pInput.type() == Input::Object) {
1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // In relocatable files, st_value holds alignment constraints for a symbol
1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // whose section index is SHN_COMMON
1346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (pShndx == llvm::ELF::SHN_COMMON || pShndx == llvm::ELF::SHN_ABS) {
1356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return pValue;
1366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
13837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    // In relocatable files, st_value holds a section offset for a defined
13937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    // symbol.
1406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // TODO:
14137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    // if --just-symbols option are enabled, convert the value from section
14237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    // offset
1436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // to virtual address by adding input section's virtual address.
1446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // The section's virtual address in relocatable files is normally zero, but
1456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // people can use link script to change it.
1466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return pValue;
1476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // In executable and shared object files, st_value holds a virtual address.
150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  // the virtual address is needed for alias identification.
151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return pValue;
1526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
1536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
15437b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
155