Merge branch 'master' of https://github.com/pret/pokeemerald into porymap-6

This commit is contained in:
GriffinR
2024-10-15 22:02:40 -04:00
98 changed files with 281 additions and 555 deletions

View File

@@ -1,7 +1,6 @@
#include <cstdio>
#include <cstring>
#include <cstdint>
#include <map>
#include <vector>
#include <string>
#include "ramscrgen.h"
@@ -22,6 +21,7 @@ static int s_shstrtabIndex;
static std::uint32_t s_symtabOffset;
static std::uint32_t s_strtabOffset;
static std::uint32_t s_pseudoCommonSectionIndex;
static std::uint32_t s_symbolCount;
static std::uint32_t s_elfFileOffset;
@@ -101,18 +101,6 @@ static void VerifyElfIdent()
FATAL_ERROR("error: \"%s\" not little-endian ELF\n", s_elfPath.c_str());
}
static void VerifyAr()
{
char expectedMagic[8] = {'!', '<', 'a', 'r', 'c', 'h', '>', '\n'};
char magic[8];
if (std::fread(magic, 8, 1, s_file) != 1)
FATAL_ERROR("error: failed to read AR magic from \"%s\"\n", s_archiveFilePath.c_str());
if (std::memcmp(magic, expectedMagic, 8) != 0)
FATAL_ERROR("error: AR magic did not match in \"%s\"\n", s_archiveFilePath.c_str());
}
static void ReadElfHeader()
{
Seek(0x20);
@@ -123,40 +111,6 @@ static void ReadElfHeader()
s_shstrtabIndex = ReadInt16();
}
static void FindArObj()
{
char file_ident[17] = {0};
char filesize_s[11] = {0};
char expectedEndMagic[2] = { 0x60, 0x0a };
char end_magic[2];
std::size_t filesize;
Seek(8);
while (!std::feof(s_file)) {
if (std::fread(file_ident, 16, 1, s_file) != 1)
FATAL_ERROR("error: failed to read file ident in \"%s\"\n", s_archiveFilePath.c_str());
Skip(32);
if (std::fread(filesize_s, 10, 1, s_file) != 1)
FATAL_ERROR("error: failed to read filesize in \"%s\"\n", s_archiveFilePath.c_str());
if (std::fread(end_magic, 2, 1, s_file) != 1)
FATAL_ERROR("error: failed to read end sentinel in \"%s\"\n", s_archiveFilePath.c_str());
if (std::memcmp(end_magic, expectedEndMagic, 2) != 0)
FATAL_ERROR("error: corrupted archive header in \"%s\" at \"%s\"\n", s_archiveFilePath.c_str(), file_ident);
char * ptr = std::strchr(file_ident, '/');
if (ptr != nullptr)
*ptr = 0;
filesize = std::strtoul(filesize_s, nullptr, 10);
if (std::strncmp(s_archiveObjectPath.c_str(), file_ident, 16) == 0) {
s_elfFileOffset = std::ftell(s_file);
return;
}
Skip(filesize);
}
FATAL_ERROR("error: could not find object \"%s\" in archive \"%s\"\n", s_archiveObjectPath.c_str(), s_archiveFilePath.c_str());
}
static std::string GetSectionName(std::uint32_t shstrtabOffset, int index)
{
Seek(s_sectionHeaderOffset + s_sectionHeaderEntrySize * index);
@@ -169,6 +123,7 @@ static void FindTableOffsets()
{
s_symtabOffset = 0;
s_strtabOffset = 0;
s_pseudoCommonSectionIndex = 0;
Seek(s_sectionHeaderOffset + s_sectionHeaderEntrySize * s_shstrtabIndex + 0x10);
std::uint32_t shstrtabOffset = ReadInt32();
@@ -192,6 +147,11 @@ static void FindTableOffsets()
FATAL_ERROR("error: mutiple .strtab sections found in \"%s\"\n", s_elfPath.c_str());
Seek(s_sectionHeaderOffset + s_sectionHeaderEntrySize * i + 0x10);
s_strtabOffset = ReadInt32();
} else if (name == "common_data") {
if (s_pseudoCommonSectionIndex) {
FATAL_ERROR("error: mutiple common_data sections found in \"%s\"\n", s_elfPath.c_str());
}
s_pseudoCommonSectionIndex = i;
}
}
@@ -202,65 +162,50 @@ static void FindTableOffsets()
FATAL_ERROR("error: couldn't find .strtab section in \"%s\"\n", s_elfPath.c_str());
}
static std::map<std::string, std::uint32_t> GetCommonSymbols_Shared()
static std::vector<std::pair<std::string, std::uint32_t>> GetCommonSymbols_Shared()
{
VerifyElfIdent();
ReadElfHeader();
FindTableOffsets();
std::map<std::string, std::uint32_t> commonSymbols;
std::vector<std::pair<std::string, std::uint32_t>> commonSymbols;
std::vector<Symbol> commonSymbolVec;
Seek(s_symtabOffset);
for (std::uint32_t i = 0; i < s_symbolCount; i++)
{
Symbol sym;
sym.nameOffset = ReadInt32();
Skip(4);
sym.size = ReadInt32();
Skip(2);
std::uint16_t sectionIndex = ReadInt16();
if (sectionIndex == SHN_COMMON)
commonSymbolVec.push_back(sym);
}
for (const Symbol& sym : commonSymbolVec)
{
Seek(s_strtabOffset + sym.nameOffset);
std::string name = ReadString();
commonSymbols[name] = sym.size;
if (s_pseudoCommonSectionIndex) {
std::vector<Symbol> commonSymbolVec;
Seek(s_symtabOffset);
for (std::uint32_t i = 0; i < s_symbolCount; i++)
{
Symbol sym;
sym.nameOffset = ReadInt32();
Skip(4);
sym.size = ReadInt32();
Skip(2);
std::uint16_t sectionIndex = ReadInt16();
if (sectionIndex == s_pseudoCommonSectionIndex)
commonSymbolVec.push_back(sym);
}
for (const Symbol& sym : commonSymbolVec)
{
Seek(s_strtabOffset + sym.nameOffset);
std::string name = ReadString();
if (name == "$d" || name == "") {
continue;
}
commonSymbols.emplace_back(name, sym.size);
}
}
return commonSymbols;
}
std::map<std::string, std::uint32_t> GetCommonSymbolsFromLib(std::string sourcePath, std::string libpath)
{
std::size_t colonPos = libpath.find(':');
if (colonPos == std::string::npos)
FATAL_ERROR("error: missing colon separator in libfile \"%s\"\n", s_elfPath.c_str());
s_archiveObjectPath = libpath.substr(colonPos + 1);
s_archiveFilePath = sourcePath + "/" + libpath.substr(1, colonPos - 1);
s_elfPath = sourcePath + "/" + libpath.substr(1);
s_file = std::fopen(s_archiveFilePath.c_str(), "rb");
if (s_file == NULL)
FATAL_ERROR("error: failed to open \"%s\" for reading\n", s_archiveFilePath.c_str());
VerifyAr();
FindArObj();
return GetCommonSymbols_Shared();
}
std::map<std::string, std::uint32_t> GetCommonSymbols(std::string sourcePath, std::string path)
std::vector<std::pair<std::string, std::uint32_t>> GetCommonSymbols(std::string sourcePath, std::string path)
{
s_elfFileOffset = 0;
if (path[0] == '*')
return GetCommonSymbolsFromLib(sourcePath, path);
FATAL_ERROR("error: library common syms are unsupported (filename: \"%s\")\n", path.c_str());
s_elfPath = sourcePath + "/" + path;
s_file = std::fopen(s_elfPath.c_str(), "rb");

View File

@@ -22,9 +22,9 @@
#define ELF_H
#include <cstdint>
#include <map>
#include <vector>
#include <string>
std::map<std::string, std::uint32_t> GetCommonSymbols(std::string sourcePath, std::string path);
std::vector<std::pair<std::string, std::uint32_t>> GetCommonSymbols(std::string sourcePath, std::string path);
#endif // ELF_H

View File

@@ -28,54 +28,19 @@
void HandleCommonInclude(std::string filename, std::string sourcePath, std::string symOrderPath, std::string lang)
{
auto commonSymbols = GetCommonSymbols(sourcePath, filename);
std::size_t dotIndex;
if (filename[0] == '*') {
dotIndex = filename.find_last_of(':');
filename = filename.substr(dotIndex + 1);
}
dotIndex = filename.find_last_of('.');
if (dotIndex == std::string::npos)
FATAL_ERROR("error: \"%s\" doesn't have a file extension\n", filename.c_str());
std::string symOrderFilename = filename.substr(0, dotIndex + 1) + "txt";
SymFile symFile(symOrderPath + "/" + symOrderFilename);
while (!symFile.IsAtEnd())
for (const auto& commonSym : commonSymbols)
{
symFile.HandleLangConditional(lang);
unsigned long size = commonSym.second;
std::string label = symFile.GetLabel(false);
if (label.length() == 0)
{
unsigned long length;
if (symFile.ReadInteger(length))
{
if (length & 3)
symFile.RaiseWarning("gap length %d is not multiple of 4", length);
printf(". += 0x%lX;\n", length);
}
}
else
{
if (commonSymbols.count(label) == 0)
symFile.RaiseError("no common symbol named \"%s\"", label.c_str());
unsigned long size = commonSymbols[label];
int alignment = 4;
if (size > 4)
alignment = 8;
if (size > 8)
alignment = 16;
printf(". = ALIGN(%d);\n", alignment);
printf("%s = .;\n", label.c_str());
printf(". += 0x%lX;\n", size);
}
symFile.ExpectEmptyRestOfLine();
int alignment = 4;
if (size > 4)
alignment = 8;
if (size > 8)
alignment = 16;
printf(". = ALIGN(%d);\n", alignment);
printf("%s = .;\n", commonSym.first.c_str());
printf(". += 0x%lX;\n", size);
}
}