16Fermer18
Kevin KoflerLe 24/02/2008 à 22:37
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;

eek sick Dommage que c'est du C++, ça pourrait être présentable à l'IOCCC sinon. grin
* 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