mirror of
https://github.com/autc04/Retro68.git
synced 2024-05-28 18:41:41 +00:00
Elf2Mac: start preparing for multiseg
This commit is contained in:
parent
a5dad80454
commit
68150e1c23
|
@ -52,42 +52,90 @@ size_t sectionHeaderStringTableIdx;
|
||||||
size_t mainStringTableIdx = (size_t)-1;
|
size_t mainStringTableIdx = (size_t)-1;
|
||||||
|
|
||||||
class Symtab;
|
class Symtab;
|
||||||
|
class Section;
|
||||||
|
|
||||||
std::vector<int> relocs;
|
std::vector<int> relocs;
|
||||||
unique_ptr<Symtab> symtab;
|
unique_ptr<Symtab> symtab;
|
||||||
|
unordered_map<string, shared_ptr<Section>> sections;
|
||||||
|
unordered_map<int, shared_ptr<Section>> sectionsByElfIndex;
|
||||||
|
|
||||||
|
std::vector<shared_ptr<Section>> codeSections;
|
||||||
|
shared_ptr<Section> dataSection;
|
||||||
|
|
||||||
|
enum class SectionKind
|
||||||
|
{
|
||||||
|
code,
|
||||||
|
data,
|
||||||
|
bss
|
||||||
|
};
|
||||||
|
|
||||||
|
class Symbol : public GElf_Sym
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool valid;
|
||||||
|
|
||||||
|
Symbol();
|
||||||
|
Symbol(GElf_Sym sym);
|
||||||
|
};
|
||||||
|
|
||||||
|
Symbol::Symbol()
|
||||||
|
: valid(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Symbol::Symbol(GElf_Sym sym)
|
||||||
|
: GElf_Sym(sym), valid(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
class Symtab
|
class Symtab
|
||||||
{
|
{
|
||||||
|
vector<Symbol> symbols;
|
||||||
public:
|
public:
|
||||||
Elf_Scn *elfsec;
|
Elf_Scn *elfsec;
|
||||||
Elf_Data *data;
|
Elf_Data *data;
|
||||||
|
|
||||||
Symtab(Elf_Scn *elfsec);
|
Symtab(Elf_Scn *elfsec);
|
||||||
|
|
||||||
GElf_Sym GetSym(int idx);
|
Symbol& GetSym(int idx);
|
||||||
};
|
};
|
||||||
|
|
||||||
Symtab::Symtab(Elf_Scn *elfsec)
|
Symtab::Symtab(Elf_Scn *elfsec)
|
||||||
: elfsec(elfsec)
|
: elfsec(elfsec)
|
||||||
{
|
{
|
||||||
data = elf_getdata(elfsec, NULL);
|
data = elf_getdata(elfsec, NULL);
|
||||||
|
|
||||||
|
GElf_Shdr shdr;
|
||||||
|
gelf_getshdr(elfsec, &shdr);
|
||||||
|
|
||||||
|
int count = shdr.sh_size / shdr.sh_entsize;
|
||||||
|
symbols.resize(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
GElf_Sym Symtab::GetSym(int idx)
|
Symbol &Symtab::GetSym(int idx)
|
||||||
{
|
{
|
||||||
GElf_Sym sym;
|
if(symbols[idx].valid)
|
||||||
auto res = gelf_getsym(data, idx, &sym);
|
return symbols[idx];
|
||||||
assert(res != 0);
|
else
|
||||||
return sym;
|
{
|
||||||
|
GElf_Sym sym;
|
||||||
|
auto res = gelf_getsym(data, idx, &sym);
|
||||||
|
assert(res != 0);
|
||||||
|
|
||||||
|
return (symbols[idx] = Symbol(sym));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Section
|
class Section
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
string name;
|
||||||
|
SectionKind kind;
|
||||||
Elf_Scn *elfsec, *relasec;
|
Elf_Scn *elfsec, *relasec;
|
||||||
Elf_Data *data;
|
Elf_Data *data;
|
||||||
|
|
||||||
Section(int idx, Elf_Scn *elfsec);
|
Section(string name, SectionKind kind, Elf_Scn *elfsec);
|
||||||
void SetRela(Elf_Scn *scn);
|
void SetRela(Elf_Scn *scn);
|
||||||
|
|
||||||
uint32_t GetSize();
|
uint32_t GetSize();
|
||||||
|
@ -95,8 +143,8 @@ public:
|
||||||
string GetAbsRelocations();
|
string GetAbsRelocations();
|
||||||
};
|
};
|
||||||
|
|
||||||
Section::Section(int idx, Elf_Scn *elfsec)
|
Section::Section(string name, SectionKind kind, Elf_Scn *elfsec)
|
||||||
: elfsec(elfsec), relasec(NULL)
|
: name(name), kind(kind), elfsec(elfsec), relasec(NULL)
|
||||||
{
|
{
|
||||||
data = elf_getdata(elfsec, NULL);
|
data = elf_getdata(elfsec, NULL);
|
||||||
}
|
}
|
||||||
|
@ -155,7 +203,6 @@ string Section::GetAbsRelocations()
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
unordered_map<string, shared_ptr<Section>> sections;
|
|
||||||
|
|
||||||
void GrokELF(string input)
|
void GrokELF(string input)
|
||||||
{
|
{
|
||||||
|
@ -203,29 +250,41 @@ void GrokELF(string input)
|
||||||
if(shdr.sh_type == SHT_PROGBITS
|
if(shdr.sh_type == SHT_PROGBITS
|
||||||
&& !bssSection) // ignore everything after bss, that's just debug info
|
&& !bssSection) // ignore everything after bss, that's just debug info
|
||||||
{
|
{
|
||||||
sections.emplace(name, make_shared<Section>(idx, scn));
|
SectionKind kind = name == ".data" ? SectionKind::data : SectionKind::code;
|
||||||
|
auto section = make_shared<Section>(name,kind, scn);
|
||||||
|
|
||||||
|
sections[name] = sectionsByElfIndex[idx] = section;
|
||||||
|
if(kind == SectionKind::data)
|
||||||
|
dataSection = section;
|
||||||
|
else if(kind == SectionKind::code)
|
||||||
|
codeSections.push_back(section);
|
||||||
}
|
}
|
||||||
if(shdr.sh_type == SHT_NOBITS)
|
if(shdr.sh_type == SHT_NOBITS)
|
||||||
{
|
{
|
||||||
bssSection = scn;
|
bssSection = scn;
|
||||||
// Currently, the bss section is only used here
|
// Currently, the bss section is used
|
||||||
// to know when to start skipping debug info sections.
|
// to know when to start skipping debug info sections.
|
||||||
// (What's the official way to distinguish a debug info section from a "real" section?)
|
// (What's the official way to distinguish a debug info section from a "real" section?)
|
||||||
|
|
||||||
// We don't even need to remember the size of address of the bss segment,
|
sections[name] = sectionsByElfIndex[idx] =
|
||||||
// the initialization code in libretro/relocate.c knows this from
|
make_shared<Section>(name,SectionKind::bss, scn);
|
||||||
// the _sbss and _ebss symbols defined in the linker script.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::sort(codeSections.begin(), codeSections.end(),
|
||||||
|
[](shared_ptr<Section> a, shared_ptr<Section> b) { return a->name < b->name; });
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlatCode(std::ostream& out)
|
void FlatCode(std::ostream& out)
|
||||||
{
|
{
|
||||||
out << sections[".text"]->GetData();
|
for(auto sec : codeSections)
|
||||||
out << sections[".data"]->GetData();
|
out << sec->GetData();
|
||||||
|
|
||||||
out << sections[".text"]->GetAbsRelocations();
|
out << dataSection->GetData();
|
||||||
out << sections[".data"]->GetAbsRelocations();
|
|
||||||
|
for(auto sec : codeSections)
|
||||||
|
out << sec->GetAbsRelocations();
|
||||||
|
out << dataSection->GetAbsRelocations();
|
||||||
longword(out, -1);
|
longword(out, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,6 +436,16 @@ int main(int argc, char *argv[])
|
||||||
elf2mac = true;
|
elf2mac = true;
|
||||||
flatoutput = true;
|
flatoutput = true;
|
||||||
}
|
}
|
||||||
|
else if(*p == "--mac-segments")
|
||||||
|
{
|
||||||
|
elf2mac = true;
|
||||||
|
if(flatoutput)
|
||||||
|
errx(EXIT_FAILURE, "--mac-segments can't be used with --mac-flat");
|
||||||
|
++p;
|
||||||
|
if(p == e)
|
||||||
|
errx(EXIT_FAILURE, "--mac-segments missing argument");
|
||||||
|
//segmentMapFile = *p;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
args2.push_back(*p);
|
args2.push_back(*p);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user