Voici le même code dans
ld-tigcc,
MakePrgm et
obj2ti.
ld-tigcc:
case AMIGAOS_HUNK_RELOC_REL1:
case AMIGAOS_HUNK_RELOC_REL2:
case AMIGAOS_HUNK_RELOC_REL4:
case AMIGAOS_HUNK_RELOC_ABS2:
case AMIGAOS_HUNK_RELOC_ABS4:
// make sure we have a section to put those relocs into
if (!currSection)
FailWithError("Relocation hunk (type `0x%lX') without context.",(long)hunkType);
{
SIZE relocSize = 0;
BOOLEAN relative = FALSE;
switch (hunkType) {
case AMIGAOS_HUNK_RELOC_REL1:
relative = TRUE;
relocSize = 1;
break;
case AMIGAOS_HUNK_RELOC_REL2:
relative = TRUE;
case AMIGAOS_HUNK_RELOC_ABS2:
relocSize = 2;
break;
case AMIGAOS_HUNK_RELOC_REL4:
relative = TRUE;
case AMIGAOS_HUNK_RELOC_ABS4:
relocSize = 4;
break;
}
hunkSize = GetNextTI4(ptr); // hunkSize is the number of relocs here.
while (hunkSize) {
OFFSET targetHunkNumber = GetNextTI4(ptr);
SECTION *targetHunk;
OFFSET i;
// allocate space for at least one more reloc target hunk
while ((SIZE) ((targetHunkNumber+1) * sizeof(SECTION*)) > relocTargetHunksSize) {
relocTargetHunks = crealloc(relocTargetHunks, relocTargetHunksSize,
relocTargetHunksSize+RELOC_TARGET_HUNKS_INCREMENT);
TestMem(relocTargetHunks);
relocTargetHunksSize += RELOC_TARGET_HUNKS_INCREMENT;
}
targetHunk = relocTargetHunks[targetHunkNumber];
if (!targetHunk) {
// create placeholder for section right now
targetHunk = calloc (1, sizeof (SECTION));
TestMem(targetHunk);
// initialize the fields to something acceptable to the backend:
// the dummy section is a 0-byte BSS section
targetHunk->Parent = Program;
targetHunk->FileName = FileName;
// This will get overwritten when the real section will be read in.
// Otherwise, the "targetHunk" section reference was invalid, hence
// the name of the dummy symbol.
if (!(CreateSectionSymbol (targetHunk, "(invalid AmigaOS target section)")))
Fail ();
relocTargetHunks[targetHunkNumber] = targetHunk;
}
for (i=0; i<(SIZE)hunkSize; i++) {
RELOC *newReloc;
I4 location = GetNextTI4(ptr);
OFFSET targetOffset = 0;
BOOLEAN unoptimizable = FALSE;
#ifdef AMIGAOS_TIGCC_EXTENSIONS
unoptimizable = !!(location&AMIGAOS_RELOC_UNOPTIMIZABLE);
location &= ~AMIGAOS_RELOC_UNOPTIMIZABLE;
#endif
newReloc = calloc (1, sizeof (RELOC));
TestMem (newReloc);
newReloc->Parent = currSection;
newReloc->Location = location;
newReloc->Target.Symbol = targetHunk->SectionSymbol;
newReloc->Target.SymbolName = newReloc->Target.Symbol->Name;
newReloc->Size = relocSize;
newReloc->Relative = relative;
newReloc->Unoptimizable = unoptimizable;
if ((OFFSET) (location+relocSize) <= currSection->Size) {
if (currSection->Data) {
targetOffset = ReadSTI(currSection->Data+location,relocSize);
// Zero out the section contents.
memset(currSection->Data+location,0,relocSize);
// We have to guess the first bytes of the targetOffset. This is
// the easiest way to do it.
if (targetHunk != currSection) {
OFFSET maxDistance = 1 << ((relocSize * 8) - 1);
// If the section is in front of the current section,
// set the reference location as close to the end as possible.
if (targetHunkNumber < (numRelocTargetHunks - 1)) {
location = targetHunk->Size - (maxDistance - 1);
// Otherwise, set the reference location as close to the start as possible.
} else {
location = maxDistance;
}
}
{
SI4 difference = targetOffset - location;
if (relocSize <= 1) {
targetOffset = location + ((SI1) difference);
} else if (relocSize <= 2) {
targetOffset = location + ((SI2) difference);
}
}
} else {
Warning(FileName,"Adding reloc at 0x%lX in section `%s' without data to section `%s'.",(long)location,currSection->SectionSymbol->Name,newReloc->Target.SymbolName);
}
} else {
Warning(FileName,"Invalid reloc location `0x%lX' in size 4 reloc table for origin section `%s' and target section `%s'",(long)location,currSection->SectionSymbol->Name,newReloc->Target.SymbolName);
}
// Apply architecture-specific fixes to the offset.
newReloc->Target.Offset = ((currSection->Code && newReloc->Target.Symbol->Parent->Code) ? M68kFixTargetOffset (targetOffset, newReloc->Size, newReloc->Relative) : targetOffset);
// Calculate the remaining part of the offset.
newReloc->FixedOffset = targetOffset - newReloc->Target.Offset;
// Put this reloc into the linked list.
InsertReloc(currSection,newReloc);
}
hunkSize = GetNextTI4(ptr);
}
}
break;
* Tout est commenté.
* Toutes les fonctionnalités du format sont gérées et le format interne garde toutes les informations nécessaires pour pouvoir linker, ce qui explique la longueur du code.
* Les noms de variables sont clairs.
MakePrgm:
else if (hunk==HunkR32)
{
// Read each section's relocations
while (1)
{
int count=ReadDWord(fp);
if (!count) break;
int section=ReadDWord(fp);
if ((section==RelocCode)||(section==RelocBSS))
{
// Check to see if the section has already been defined
if (reloc[section].ofs)
{
printf("Error: Duplicate or split relocation information\n");
return 1;
}
reloc[section].count=count;
reloc[section].ofs=new int[count];
// Read in the relocation info
for (int i=0;i<count;i++)
reloc[section].ofs[i]=0x7FFFFFFFUL & ReadDWord(fp);
}
else
{
// Unknown section number, so skip relocations
for (int i=0;i<count;i++)
ReadDWord(fp);
}
}
}
else if (hunk==HunkR16)
{
printf("Error: 16-bit relocations are unsupported\n");
return 1;
}
else if (hunk==HunkR8)
{
printf("Error: 8-bit relocations are unsupported\n");
return 1;
}
Acceptable, mais:
* très peu de commentaires
* utilisation d'abbréviations comme
ofs et
fp
* représentation interne insuffisante pour pouvoir faire du vrai linking
* les relogements relatifs, vous connaissez?
obj2ti:
case HunkR16:
fprintf (stderr, "Warning: 16-bit relocations are unsupported.\n");
for (; size>0 && n; n=br4 (am))
n += 2, am += n, size -= n;
am++; size--; break;
case HunkR32:
if (CurHunk < 0) return OBJERR_R32Hunk;
else {
for (; size>0 && n; n=br4 (am)) {
DWORD k = br4 (++am);
if (k < 3 && !Hunk[CurHunk].R32[k]) {
unsigned long *R32;
Hunk[CurHunk].nR32[k] = n;
Hunk[CurHunk].R32[k] = R32 = new unsigned long [n];
for (am++; n--; size--) *R32++ = br4 (am++);
size -= 2;
} else return OBJERR_R32Hunk;
} am++; size--;
} break;

Dommage que c'est du C++, ça pourrait être présentable à l'IOCCC sinon.
* aucun commentaire
* abbréviations obscures dans tous les sens
* nombres magiques (c'est quoi
k < 3?)
* représentation interne insuffisante pour pouvoir faire du vrai linking
* les relogements relatifs sont là aussi inconnus