mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Use automatic allocation for object file symbols
This commit is contained in:
@@ -16,7 +16,7 @@ struct Assertion {
|
|||||||
struct Patch patch; // Also used for its `.type`
|
struct Patch patch; // Also used for its `.type`
|
||||||
char *message;
|
char *message;
|
||||||
// This would be redundant with `.section->fileSymbols`... but `section` is sometimes NULL!
|
// This would be redundant with `.section->fileSymbols`... but `section` is sometimes NULL!
|
||||||
std::vector<struct Symbol *> *fileSymbols;
|
std::vector<struct Symbol> *fileSymbols;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -10,6 +10,6 @@
|
|||||||
struct FileStackNode;
|
struct FileStackNode;
|
||||||
struct Symbol;
|
struct Symbol;
|
||||||
|
|
||||||
void sdobj_ReadFile(struct FileStackNode const *fileName, FILE *file, std::vector<struct Symbol *> &fileSymbols);
|
void sdobj_ReadFile(struct FileStackNode const *fileName, FILE *file, std::vector<struct Symbol> &fileSymbols);
|
||||||
|
|
||||||
#endif // RGBDS_LINK_SDAS_OBJ_H
|
#endif // RGBDS_LINK_SDAS_OBJ_H
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ struct Section {
|
|||||||
uint8_t *data; // Array of size `size`
|
uint8_t *data; // Array of size `size`
|
||||||
std::vector<struct Patch> *patches;
|
std::vector<struct Patch> *patches;
|
||||||
// Extra info computed during linking
|
// Extra info computed during linking
|
||||||
std::vector<struct Symbol *> *fileSymbols;
|
std::vector<struct Symbol> *fileSymbols;
|
||||||
std::vector<struct Symbol *> *symbols;
|
std::vector<struct Symbol *> *symbols;
|
||||||
struct Section *nextu; // The next "component" of this unionized sect
|
struct Section *nextu; // The next "component" of this unionized sect
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
#include "linkdefs.hpp"
|
#include "linkdefs.hpp"
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
|
|
||||||
static std::deque<std::vector<struct Symbol *>> symbolLists;
|
static std::deque<std::vector<struct Symbol>> symbolLists;
|
||||||
static std::vector<std::vector<struct FileStackNode>> nodes;
|
static std::vector<std::vector<struct FileStackNode>> nodes;
|
||||||
static std::deque<struct Assertion> assertions;
|
static std::deque<struct Assertion> assertions;
|
||||||
|
|
||||||
@@ -385,20 +385,20 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam
|
|||||||
* @param symbol The symbol to link
|
* @param symbol The symbol to link
|
||||||
* @param section The section to link
|
* @param section The section to link
|
||||||
*/
|
*/
|
||||||
static void linkSymToSect(struct Symbol *symbol, struct Section *section)
|
static void linkSymToSect(struct Symbol &symbol, struct Section *section)
|
||||||
{
|
{
|
||||||
uint32_t a = 0, b = section->symbols->size();
|
uint32_t a = 0, b = section->symbols->size();
|
||||||
|
|
||||||
while (a != b) {
|
while (a != b) {
|
||||||
uint32_t c = (a + b) / 2;
|
uint32_t c = (a + b) / 2;
|
||||||
|
|
||||||
if ((*section->symbols)[c]->offset > symbol->offset)
|
if ((*section->symbols)[c]->offset > symbol.offset)
|
||||||
b = c;
|
b = c;
|
||||||
else
|
else
|
||||||
a = c + 1;
|
a = c + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
section->symbols->insert(section->symbols->begin() + a, symbol);
|
section->symbols->insert(section->symbols->begin() + a, &symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -465,7 +465,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
|
|||||||
if (!where.name)
|
if (!where.name)
|
||||||
fatal(NULL, 0, "Failed to duplicate \"%s\"'s name: %s", fileName, strerror(errno));
|
fatal(NULL, 0, "Failed to duplicate \"%s\"'s name: %s", fileName, strerror(errno));
|
||||||
|
|
||||||
std::vector<struct Symbol *> &fileSymbols = symbolLists.emplace_front();
|
std::vector<struct Symbol> &fileSymbols = symbolLists.emplace_front();
|
||||||
|
|
||||||
sdobj_ReadFile(&where, file, fileSymbols);
|
sdobj_ReadFile(&where, file, fileSymbols);
|
||||||
return;
|
return;
|
||||||
@@ -505,23 +505,20 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
|
|||||||
readFileStackNode(file, nodes[fileID], i, fileName);
|
readFileStackNode(file, nodes[fileID], i, fileName);
|
||||||
|
|
||||||
// This file's symbols, kept to link sections to them
|
// This file's symbols, kept to link sections to them
|
||||||
std::vector<struct Symbol *> &fileSymbols = symbolLists.emplace_front(nbSymbols);
|
std::vector<struct Symbol> &fileSymbols = symbolLists.emplace_front(nbSymbols);
|
||||||
std::vector<uint32_t> nbSymPerSect(nbSections, 0);
|
std::vector<uint32_t> nbSymPerSect(nbSections, 0);
|
||||||
|
|
||||||
verbosePrint("Reading %" PRIu32 " symbols...\n", nbSymbols);
|
verbosePrint("Reading %" PRIu32 " symbols...\n", nbSymbols);
|
||||||
for (uint32_t i = 0; i < nbSymbols; i++) {
|
for (uint32_t i = 0; i < nbSymbols; i++) {
|
||||||
// Read symbol
|
// Read symbol
|
||||||
struct Symbol *symbol = (struct Symbol *)malloc(sizeof(*symbol));
|
struct Symbol &symbol = fileSymbols[i];
|
||||||
|
|
||||||
if (!symbol)
|
readSymbol(file, &symbol, fileName, nodes[fileID]);
|
||||||
err("%s: Failed to create new symbol", fileName);
|
|
||||||
readSymbol(file, symbol, fileName, nodes[fileID]);
|
|
||||||
|
|
||||||
fileSymbols[i] = symbol;
|
if (symbol.type == SYMTYPE_EXPORT)
|
||||||
if (symbol->type == SYMTYPE_EXPORT)
|
sym_AddSymbol(&symbol);
|
||||||
sym_AddSymbol(symbol);
|
if (symbol.sectionID != -1)
|
||||||
if (symbol->sectionID != -1)
|
nbSymPerSect[symbol.sectionID]++;
|
||||||
nbSymPerSect[symbol->sectionID]++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This file's sections, stored in a table to link symbols to them
|
// This file's sections, stored in a table to link symbols to them
|
||||||
@@ -555,10 +552,10 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
|
|||||||
|
|
||||||
// Give symbols' section pointers to their sections
|
// Give symbols' section pointers to their sections
|
||||||
for (uint32_t i = 0; i < nbSymbols; i++) {
|
for (uint32_t i = 0; i < nbSymbols; i++) {
|
||||||
int32_t sectionID = fileSymbols[i]->sectionID;
|
int32_t sectionID = fileSymbols[i].sectionID;
|
||||||
|
|
||||||
if (sectionID == -1) {
|
if (sectionID == -1) {
|
||||||
fileSymbols[i]->section = NULL;
|
fileSymbols[i].section = NULL;
|
||||||
} else {
|
} else {
|
||||||
struct Section *section = fileSections[sectionID];
|
struct Section *section = fileSections[sectionID];
|
||||||
|
|
||||||
@@ -568,10 +565,10 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
|
|||||||
if (section->modifier != SECTION_NORMAL) {
|
if (section->modifier != SECTION_NORMAL) {
|
||||||
if (section->modifier == SECTION_FRAGMENT)
|
if (section->modifier == SECTION_FRAGMENT)
|
||||||
// Add the fragment's offset to the symbol's
|
// Add the fragment's offset to the symbol's
|
||||||
fileSymbols[i]->offset += section->offset;
|
fileSymbols[i].offset += section->offset;
|
||||||
section = getMainSection(section);
|
section = getMainSection(section);
|
||||||
}
|
}
|
||||||
fileSymbols[i]->section = section;
|
fileSymbols[i].section = section;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,12 +627,6 @@ static void freeSection(struct Section *section)
|
|||||||
} while (section);
|
} while (section);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void freeSymbol(struct Symbol *symbol)
|
|
||||||
{
|
|
||||||
free(symbol->name);
|
|
||||||
free(symbol);
|
|
||||||
}
|
|
||||||
|
|
||||||
void obj_Cleanup(void)
|
void obj_Cleanup(void)
|
||||||
{
|
{
|
||||||
for (std::vector<struct FileStackNode> &fileNodes : nodes) {
|
for (std::vector<struct FileStackNode> &fileNodes : nodes) {
|
||||||
@@ -648,9 +639,9 @@ void obj_Cleanup(void)
|
|||||||
sect_ForEach(freeSection);
|
sect_ForEach(freeSection);
|
||||||
sect_CleanupSections();
|
sect_CleanupSections();
|
||||||
|
|
||||||
for (std::vector<struct Symbol *> &fileSymbols : symbolLists) {
|
for (std::vector<struct Symbol> &fileSymbols : symbolLists) {
|
||||||
for (struct Symbol *symbol : fileSymbols)
|
for (struct Symbol &symbol : fileSymbols)
|
||||||
freeSymbol(symbol);
|
free(symbol.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (struct Assertion &assert : assertions)
|
for (struct Assertion &assert : assertions)
|
||||||
|
|||||||
@@ -56,16 +56,16 @@ static uint32_t getRPNByte(uint8_t const **expression, int32_t *size,
|
|||||||
return *(*expression)++;
|
return *(*expression)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct Symbol const *getSymbol(std::vector<struct Symbol *> const &symbolList, uint32_t index)
|
static struct Symbol const *getSymbol(std::vector<struct Symbol> const &symbolList, uint32_t index)
|
||||||
{
|
{
|
||||||
assert(index != (uint32_t)-1); // PC needs to be handled specially, not here
|
assert(index != (uint32_t)-1); // PC needs to be handled specially, not here
|
||||||
struct Symbol *symbol = symbolList[index];
|
struct Symbol const &symbol = symbolList[index];
|
||||||
|
|
||||||
// If the symbol is defined elsewhere...
|
// If the symbol is defined elsewhere...
|
||||||
if (symbol->type == SYMTYPE_IMPORT)
|
if (symbol.type == SYMTYPE_IMPORT)
|
||||||
return sym_GetSymbol(symbol->name);
|
return sym_GetSymbol(symbol.name);
|
||||||
|
|
||||||
return symbol;
|
return &symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -77,7 +77,7 @@ static struct Symbol const *getSymbol(std::vector<struct Symbol *> const &symbol
|
|||||||
* errors caused by the value should be suppressed.
|
* errors caused by the value should be suppressed.
|
||||||
*/
|
*/
|
||||||
static int32_t computeRPNExpr(struct Patch const *patch,
|
static int32_t computeRPNExpr(struct Patch const *patch,
|
||||||
std::vector<struct Symbol *> const &fileSymbols)
|
std::vector<struct Symbol> const &fileSymbols)
|
||||||
{
|
{
|
||||||
// Small shortcut to avoid a lot of repetition
|
// Small shortcut to avoid a lot of repetition
|
||||||
#define popRPN() popRPN(patch->src, patch->lineNo)
|
#define popRPN() popRPN(patch->src, patch->lineNo)
|
||||||
@@ -224,13 +224,13 @@ static int32_t computeRPNExpr(struct Patch const *patch,
|
|||||||
if (!symbol) {
|
if (!symbol) {
|
||||||
error(patch->src, patch->lineNo,
|
error(patch->src, patch->lineNo,
|
||||||
"Requested BANK() of symbol \"%s\", which was not found",
|
"Requested BANK() of symbol \"%s\", which was not found",
|
||||||
fileSymbols[value]->name);
|
fileSymbols[value].name);
|
||||||
isError = true;
|
isError = true;
|
||||||
value = 1;
|
value = 1;
|
||||||
} else if (!symbol->section) {
|
} else if (!symbol->section) {
|
||||||
error(patch->src, patch->lineNo,
|
error(patch->src, patch->lineNo,
|
||||||
"Requested BANK() of non-label symbol \"%s\"",
|
"Requested BANK() of non-label symbol \"%s\"",
|
||||||
fileSymbols[value]->name);
|
fileSymbols[value].name);
|
||||||
isError = true;
|
isError = true;
|
||||||
value = 1;
|
value = 1;
|
||||||
} else {
|
} else {
|
||||||
@@ -385,7 +385,7 @@ static int32_t computeRPNExpr(struct Patch const *patch,
|
|||||||
|
|
||||||
if (!symbol) {
|
if (!symbol) {
|
||||||
error(patch->src, patch->lineNo,
|
error(patch->src, patch->lineNo,
|
||||||
"Unknown symbol \"%s\"", fileSymbols[value]->name);
|
"Unknown symbol \"%s\"", fileSymbols[value].name);
|
||||||
isError = true;
|
isError = true;
|
||||||
} else {
|
} else {
|
||||||
value = symbol->value;
|
value = symbol->value;
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ enum RelocFlags {
|
|||||||
| 1 << RELOC_EXPR24 | 1 << RELOC_BANKBYTE,
|
| 1 << RELOC_EXPR24 | 1 << RELOC_BANKBYTE,
|
||||||
};
|
};
|
||||||
|
|
||||||
void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<struct Symbol *> &fileSymbols) {
|
void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<struct Symbol> &fileSymbols) {
|
||||||
size_t bufLen = 256;
|
size_t bufLen = 256;
|
||||||
char *line = (char *)malloc(bufLen);
|
char *line = (char *)malloc(bufLen);
|
||||||
char const *token;
|
char const *token;
|
||||||
@@ -369,59 +369,55 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
if (nbSymbols == expectedNbSymbols)
|
if (nbSymbols == expectedNbSymbols)
|
||||||
warning(where, lineNo, "Got more 'S' lines than the expected %" PRIu32,
|
warning(where, lineNo, "Got more 'S' lines than the expected %" PRIu32,
|
||||||
expectedNbSymbols);
|
expectedNbSymbols);
|
||||||
struct Symbol *symbol = (struct Symbol *)malloc(sizeof(*symbol));
|
struct Symbol &symbol = fileSymbols.emplace_back();
|
||||||
|
|
||||||
if (!symbol)
|
|
||||||
fatal(where, lineNo, "Failed to alloc symbol: %s", strerror(errno));
|
|
||||||
fileSymbols.push_back(symbol);
|
|
||||||
|
|
||||||
// Init other members
|
// Init other members
|
||||||
symbol->objFileName = where->name;
|
symbol.objFileName = where->name;
|
||||||
symbol->src = where;
|
symbol.src = where;
|
||||||
symbol->lineNo = lineNo;
|
symbol.lineNo = lineNo;
|
||||||
|
|
||||||
// No need to set the `sectionID`, since we can directly set the pointer
|
// No need to set the `sectionID`, since we can directly set the pointer
|
||||||
symbol->section = nbSections != 0 ? fileSections[nbSections - 1].section : NULL;
|
symbol.section = nbSections != 0 ? fileSections[nbSections - 1].section : NULL;
|
||||||
|
|
||||||
getToken(line, "'S' line is too short");
|
getToken(line, "'S' line is too short");
|
||||||
symbol->name = strdup(token);
|
symbol.name = strdup(token);
|
||||||
if (!symbol->name)
|
if (!symbol.name)
|
||||||
fatal(where, lineNo, "Failed to alloc symbol name: %s", strerror(errno));
|
fatal(where, lineNo, "Failed to alloc symbol name: %s", strerror(errno));
|
||||||
|
|
||||||
getToken(NULL, "'S' line is too short");
|
getToken(NULL, "'S' line is too short");
|
||||||
// It might be an `offset`, but both types are the same so type punning is fine
|
// It might be an `offset`, but both types are the same so type punning is fine
|
||||||
symbol->value = parseNumber(where, lineNo, &token[3], numberType);
|
symbol.value = parseNumber(where, lineNo, &token[3], numberType);
|
||||||
if (symbol->section && symbol->section->isAddressFixed) {
|
if (symbol.section && symbol.section->isAddressFixed) {
|
||||||
assert(symbol->offset >= symbol->section->org);
|
assert(symbol.offset >= symbol.section->org);
|
||||||
symbol->offset -= symbol->section->org;
|
symbol.offset -= symbol.section->org;
|
||||||
assert(symbol->offset <= symbol->section->size);
|
assert(symbol.offset <= symbol.section->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expected format: /[DR]ef[0-9A-F]+/i
|
// Expected format: /[DR]ef[0-9A-F]+/i
|
||||||
if (token[0] == 'R' || token[0] == 'r') {
|
if (token[0] == 'R' || token[0] == 'r') {
|
||||||
symbol->type = SYMTYPE_IMPORT;
|
symbol.type = SYMTYPE_IMPORT;
|
||||||
// TODO: hard error if the rest is not zero
|
// TODO: hard error if the rest is not zero
|
||||||
} else if (token[0] != 'D' && token[0] != 'd') {
|
} else if (token[0] != 'D' && token[0] != 'd') {
|
||||||
fatal(where, lineNo, "'S' line is neither \"Def\" nor \"Ref\"");
|
fatal(where, lineNo, "'S' line is neither \"Def\" nor \"Ref\"");
|
||||||
} else {
|
} else {
|
||||||
// All symbols are exported
|
// All symbols are exported
|
||||||
symbol->type = SYMTYPE_EXPORT;
|
symbol.type = SYMTYPE_EXPORT;
|
||||||
struct Symbol const *other = sym_GetSymbol(symbol->name);
|
struct Symbol const *other = sym_GetSymbol(symbol.name);
|
||||||
|
|
||||||
if (other) {
|
if (other) {
|
||||||
// The same symbol can only be defined twice if neither
|
// The same symbol can only be defined twice if neither
|
||||||
// definition is in a floating section
|
// definition is in a floating section
|
||||||
if ((other->section && !other->section->isAddressFixed)
|
if ((other->section && !other->section->isAddressFixed)
|
||||||
|| (symbol->section && !symbol->section->isAddressFixed)) {
|
|| (symbol.section && !symbol.section->isAddressFixed)) {
|
||||||
sym_AddSymbol(symbol); // This will error out
|
sym_AddSymbol(&symbol); // This will error out
|
||||||
} else if (other->value != symbol->value) {
|
} else if (other->value != symbol.value) {
|
||||||
error(where, lineNo,
|
error(where, lineNo,
|
||||||
"Definition of \"%s\" conflicts with definition in %s (%" PRId32 " != %" PRId32 ")",
|
"Definition of \"%s\" conflicts with definition in %s (%" PRId32 " != %" PRId32 ")",
|
||||||
symbol->name, other->objFileName, symbol->value, other->value);
|
symbol.name, other->objFileName, symbol.value, other->value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Add a new definition
|
// Add a new definition
|
||||||
sym_AddSymbol(symbol);
|
sym_AddSymbol(&symbol);
|
||||||
}
|
}
|
||||||
// It's fine to keep modifying the symbol after `AddSymbol`, only
|
// It's fine to keep modifying the symbol after `AddSymbol`, only
|
||||||
// the name must not be modified
|
// the name must not be modified
|
||||||
@@ -430,7 +426,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
fatal(where, lineNo, "'S' line is neither \"Def\" nor \"Ref\"");
|
fatal(where, lineNo, "'S' line is neither \"Def\" nor \"Ref\"");
|
||||||
|
|
||||||
if (nbSections != 0)
|
if (nbSections != 0)
|
||||||
fileSections[nbSections - 1].section->symbols->push_back(symbol);
|
fileSections[nbSections - 1].section->symbols->push_back(&symbol);
|
||||||
|
|
||||||
expectEol("'S' line is too long");
|
expectEol("'S' line is too long");
|
||||||
|
|
||||||
@@ -582,34 +578,34 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
if (idx >= nbSymbols)
|
if (idx >= nbSymbols)
|
||||||
fatal(where, lineNo, "Reloc refers to symbol #%" PRIu16 " out of %zu",
|
fatal(where, lineNo, "Reloc refers to symbol #%" PRIu16 " out of %zu",
|
||||||
idx, nbSymbols);
|
idx, nbSymbols);
|
||||||
struct Symbol const *sym = fileSymbols[idx];
|
struct Symbol const &sym = fileSymbols[idx];
|
||||||
|
|
||||||
// SDCC has a bunch of "magic symbols" that start with a
|
// SDCC has a bunch of "magic symbols" that start with a
|
||||||
// letter and an underscore. These are not compatibility
|
// letter and an underscore. These are not compatibility
|
||||||
// hacks, this is how SDLD actually works.
|
// hacks, this is how SDLD actually works.
|
||||||
if (sym->name[0] == 'b' && sym->name[1] == '_') {
|
if (sym.name[0] == 'b' && sym.name[1] == '_') {
|
||||||
// Look for the symbol being referenced, and use its index instead
|
// Look for the symbol being referenced, and use its index instead
|
||||||
for (idx = 0; idx < nbSymbols; ++idx) {
|
for (idx = 0; idx < nbSymbols; ++idx) {
|
||||||
if (strcmp(&sym->name[1], fileSymbols[idx]->name) == 0)
|
if (strcmp(&sym.name[1], fileSymbols[idx].name) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (idx == nbSymbols)
|
if (idx == nbSymbols)
|
||||||
fatal(where, lineNo, "\"%s\" is missing a reference to \"%s\"",
|
fatal(where, lineNo, "\"%s\" is missing a reference to \"%s\"",
|
||||||
sym->name, &sym->name[1]);
|
sym.name, &sym.name[1]);
|
||||||
patch.rpnExpression.resize(5);
|
patch.rpnExpression.resize(5);
|
||||||
patch.rpnExpression[0] = RPN_BANK_SYM;
|
patch.rpnExpression[0] = RPN_BANK_SYM;
|
||||||
patch.rpnExpression[1] = idx;
|
patch.rpnExpression[1] = idx;
|
||||||
patch.rpnExpression[2] = idx >> 8;
|
patch.rpnExpression[2] = idx >> 8;
|
||||||
patch.rpnExpression[3] = idx >> 16;
|
patch.rpnExpression[3] = idx >> 16;
|
||||||
patch.rpnExpression[4] = idx >> 24;
|
patch.rpnExpression[4] = idx >> 24;
|
||||||
} else if (sym->name[0] == 'l' && sym->name[1] == '_') {
|
} else if (sym.name[0] == 'l' && sym.name[1] == '_') {
|
||||||
patch.rpnExpression.resize(1 + strlen(&sym->name[2]) + 1);
|
patch.rpnExpression.resize(1 + strlen(&sym.name[2]) + 1);
|
||||||
patch.rpnExpression[0] = RPN_SIZEOF_SECT;
|
patch.rpnExpression[0] = RPN_SIZEOF_SECT;
|
||||||
strcpy((char *)&patch.rpnExpression[1], &sym->name[2]);
|
strcpy((char *)&patch.rpnExpression[1], &sym.name[2]);
|
||||||
} else if (sym->name[0] == 's' && sym->name[1] == '_') {
|
} else if (sym.name[0] == 's' && sym.name[1] == '_') {
|
||||||
patch.rpnExpression.resize(1 + strlen(&sym->name[2]) + 1);
|
patch.rpnExpression.resize(1 + strlen(&sym.name[2]) + 1);
|
||||||
patch.rpnExpression[0] = RPN_STARTOF_SECT;
|
patch.rpnExpression[0] = RPN_STARTOF_SECT;
|
||||||
strcpy((char *)&patch.rpnExpression[1], &sym->name[2]);
|
strcpy((char *)&patch.rpnExpression[1], &sym.name[2]);
|
||||||
} else {
|
} else {
|
||||||
patch.rpnExpression.resize(5);
|
patch.rpnExpression.resize(5);
|
||||||
patch.rpnExpression[0] = RPN_SYM;
|
patch.rpnExpression[0] = RPN_SYM;
|
||||||
|
|||||||
Reference in New Issue
Block a user