elf64.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. #include "u.h"
  2. #include "tos.h"
  3. #include "../port/lib.h"
  4. #include "mem.h"
  5. #include "dat.h"
  6. #include "fns.h"
  7. #include "../port/error.h"
  8. #include "getput.h"
  9. typedef struct Elf64_Ehdr Elf64_Ehdr;
  10. typedef struct Elf64_Phdr Elf64_Phdr;
  11. enum {
  12. EI_MAG0 = 0, // File identification
  13. EI_MAG1 = 1,
  14. EI_MAG2 = 2,
  15. EI_MAG3 = 3,
  16. EI_CLASS = 4, // File class
  17. ELFCLASS32 = 1, // 32-bit objects
  18. ELFCLASS64 = 2, // 64-bit objects
  19. EI_DATA = 5, // Data encoding
  20. ELFDATA2LSB = 1, // Object file data structures are littleendian
  21. ELFDATA2MSB = 2, // Object file data structures are bigendian
  22. EI_VERSION = 6, // File version
  23. EI_OSABI = 7, // OS/ABI identification
  24. ELFOSABI_SYSV = 0, // System V ABI
  25. ELFOSABI_HPUX = 1,
  26. EI_ABIVERSION = 8, // ABI version
  27. EI_PAD = 9, // Start of padding bytes
  28. EI_NIDENT = 16, // Size of e_ident[]
  29. ET_NONE = 0, // No file type
  30. ET_REL = 1, // Relocatable object file
  31. ET_EXEC = 2, // Executable file
  32. ET_DYN = 3, // Shared object file
  33. ET_CORE = 4, // Core file
  34. PT_NULL = 0, // Unused entry
  35. PT_LOAD = 1, // Loadable segment
  36. PT_DYNAMIC = 2, // Dynamic linking tables
  37. PT_INTERP = 3, // Program interpreter path name
  38. PT_NOTE = 4, // Note sections
  39. PT_SHLIB = 5, // Reserved
  40. PT_PHDR = 6, // Program header table
  41. EM_NONE = 0, // No
  42. EM_M32 = 1, // AT&T WE
  43. EM_SPARC = 2, //
  44. EM_386 = 3, // Intel
  45. EM_68K = 4, // Motorola
  46. EM_88K = 5, // Motorola
  47. EM_IAMCU = 6, // Intel
  48. EM_860 = 7, // Intel
  49. EM_MIPS = 8, // MIPS I
  50. EM_S370 = 9, // IBM System/370
  51. EM_MIPS_RS3_LE = 10, // MIPS RS3000
  52. // reserved
  53. EM_PARISC = 15, // Hewlett-Packard
  54. // reserved
  55. EM_VPP500 = 17, // Fujitsu
  56. EM_SPARC32PLUS = 18, // Enhanced instruction set
  57. EM_960 = 19, // Intel
  58. EM_PPC = 20, //
  59. EM_PPC64 = 21, // 64-bit
  60. EM_S390 = 22, // IBM System/390
  61. EM_SPU = 23, // IBM
  62. // reserved
  63. EM_V800 = 36, // NEC
  64. EM_FR20 = 37, // Fujitsu
  65. EM_RH32 = 38, // TRW
  66. EM_RCE = 39, // Motorola
  67. EM_ARM = 40, // ARM 32-bit architecture
  68. EM_ALPHA = 41, // Digital
  69. EM_SH = 42, // Hitachi
  70. EM_SPARCV9 = 43, // SPARC Version
  71. EM_TRICORE = 44, // Siemens TriCore embedded
  72. EM_ARC = 45, // Argonaut RISC Core, Argonaut Technologies
  73. EM_H8_300 = 46, // Hitachi
  74. EM_H8_300H = 47, // Hitachi
  75. EM_H8S = 48, // Hitachi
  76. EM_H8_500 = 49, // Hitachi
  77. EM_IA_64 = 50, // Intel IA-64 processor
  78. EM_MIPS_X = 51, // Stanford
  79. EM_COLDFIRE = 52, // Motorola
  80. EM_68HC12 = 53, // Motorola
  81. EM_MMA = 54, // Fujitsu MMA Multimedia
  82. EM_PCP = 55, // Siemens
  83. EM_NCPU = 56, // Sony nCPU embedded RISC
  84. EM_NDR1 = 57, // Denso NDR1
  85. EM_STARCORE = 58, // Motorola Star*Core
  86. EM_ME16 = 59, // Toyota ME16
  87. EM_ST100 = 60, // STMicroelectronics ST100
  88. EM_TINYJ = 61, // Advanced Logic Corp. TinyJ embedded processor
  89. EM_X86_64 = 62, // AMD x86-64
  90. EM_PDSP = 63, // Sony DSP
  91. EM_PDP10 = 64, // Digital Equipment Corp.
  92. EM_PDP11 = 65, // Digital Equipment Corp.
  93. EM_FX66 = 66, // Siemens FX66
  94. EM_ST9PLUS = 67, // STMicroelectronics ST9+ 8/16 bit
  95. EM_ST7 = 68, // STMicroelectronics ST7 8-bit
  96. EM_68HC16 = 69, // Motorola MC68HC16
  97. EM_68HC11 = 70, // Motorola MC68HC11
  98. EM_68HC08 = 71, // Motorola MC68HC08
  99. EM_68HC05 = 72, // Motorola MC68HC05
  100. EM_SVX = 73, // Silicon Graphics
  101. EM_ST19 = 74, // STMicroelectronics ST19 8-bit
  102. EM_VAX = 75, // Digital
  103. EM_CRIS = 76, // Axis Communications 32-bit embedded
  104. EM_JAVELIN = 77, // Infineon Technologies 32-bit embedded
  105. EM_FIREPATH = 78, // Element 14 64-bit DSP
  106. EM_ZSP = 79, // LSI Logic 16-bit DSP
  107. EM_MMIX = 80, // Donald Knuth's educational 64-bit
  108. EM_HUANY = 81, // Harvard University machine-independent object
  109. EM_PRISM = 82, // SiTera
  110. EM_AVR = 83, // Atmel AVR 8-bit
  111. EM_FR30 = 84, // Fujitsu
  112. EM_D10V = 85, // Mitsubishi
  113. EM_D30V = 86, // Mitsubishi
  114. EM_V850 = 87, // NEC
  115. EM_M32R = 88, // Mitsubishi
  116. EM_MN10300 = 89, // Matsushita
  117. EM_MN10200 = 90, // Matsushita
  118. EM_PJ = 91, //
  119. EM_OPENRISC = 92, // OpenRISC 32-bit embedded
  120. EM_ARC_COMPACT = 93, // ARC International ARCompact processor (old spelling/synonym:
  121. EM_XTENSA = 94, // Tensilica Xtensa
  122. EM_VIDEOCORE = 95, // Alphamosaic VideoCore
  123. EM_TMM_GPP = 96, // Thompson Multimedia General Purpose
  124. EM_NS32K = 97, // National Semiconductor 32000
  125. EM_TPC = 98, // Tenor Network TPC
  126. EM_SNP1K = 99, // Trebia SNP 1000
  127. EM_ST200 = 100, // STMicroelectronics (www.st.com) ST200
  128. EM_IP2K = 101, // Ubicom IP2xxx microcontroller
  129. EM_MAX = 102, // MAX
  130. EM_CR = 103, // National Semiconductor CompactRISC
  131. EM_F2MC16 = 104, // Fujitsu
  132. EM_MSP430 = 105, // Texas Instruments embedded microcontroller
  133. EM_BLACKFIN = 106, // Analog Devices Blackfin (DSP)
  134. EM_SE_C33 = 107, // S1C33 Family of Seiko Epson
  135. EM_SEP = 108, // Sharp embedded
  136. EM_ARCA = 109, // Arca RISC
  137. EM_UNICORE = 110, // Microprocessor series from PKU-Unity Ltd. and MPRC of Peking
  138. EM_EXCESS = 111, // eXcess: 16/32/64-bit configurable embedded
  139. EM_DXP = 112, // Icera Semiconductor Inc. Deep Execution
  140. EM_ALTERA_NIOS2 = 113, // Altera Nios II soft-core
  141. EM_CRX = 114, // National Semiconductor CompactRISC CRX
  142. EM_XGATE = 115, // Motorola XGATE embedded
  143. EM_C166 = 116, // Infineon C16x/XC16x
  144. EM_M16C = 117, // Renesas M16C series
  145. EM_DSPIC30F = 118, // Microchip Technology dsPIC30F Digital Signal
  146. EM_CE = 119, // Freescale Communication Engine RISC
  147. EM_M32C = 120, // Renesas M32C series
  148. // reserved
  149. EM_TSK3000 = 131, // Altium TSK3000
  150. EM_RS08 = 132, // Freescale RS08 embedded
  151. EM_SHARC = 133, // Analog Devices SHARC family of 32-bit DSP
  152. EM_ECOG2 = 134, // Cyan Technology eCOG2
  153. EM_SCORE7 = 135, // Sunplus S+core7 RISC
  154. EM_DSP24 = 136, // New Japan Radio (NJR) 24-bit DSP
  155. EM_VIDEOCORE3 = 137, // Broadcom VideoCore III
  156. EM_LATTICEMICO32 = 138, // RISC processor for Lattice FPGA
  157. EM_SE_C17 = 139, // Seiko Epson C17
  158. EM_TI_C6000 = 140, // The Texas Instruments TMS320C6000 DSP
  159. EM_TI_C2000 = 141, // The Texas Instruments TMS320C2000 DSP
  160. EM_TI_C5500 = 142, // The Texas Instruments TMS320C55x DSP
  161. EM_TI_ARP32 = 143, // Texas Instruments Application Specific RISC Processor, 32bit
  162. EM_TI_PRU = 144, // Texas Instruments Programmable Realtime
  163. // reserved
  164. EM_MMDSP_PLUS = 160, // STMicroelectronics 64bit VLIW Data Signal
  165. EM_CYPRESS_M8C = 161, // Cypress M8C
  166. EM_R32C = 162, // Renesas R32C series
  167. EM_TRIMEDIA = 163, // NXP Semiconductors TriMedia architecture
  168. EM_QDSP6 = 164, // QUALCOMM DSP6
  169. EM_8051 = 165, // Intel 8051 and
  170. EM_STXP7X = 166, // STMicroelectronics STxP7x family of configurable and extensible RISC
  171. EM_NDS32 = 167, // Andes Technology compact code size embedded RISC processor
  172. EM_ECOG1 = 168, // Cyan Technology eCOG1X
  173. EM_ECOG1X = 168, // Cyan Technology eCOG1X
  174. EM_MAXQ30 = 169, // Dallas Semiconductor MAXQ30 Core
  175. EM_XIMO16 = 170, // New Japan Radio (NJR) 16-bit DSP
  176. EM_MANIK = 171, // M2000 Reconfigurable RISC
  177. EM_CRAYNV2 = 172, // Cray Inc. NV2 vector
  178. EM_RX = 173, // Renesas RX
  179. EM_METAG = 174, // Imagination Technologies META processor
  180. EM_MCST_ELBRUS = 175, // MCST Elbrus general purpose hardware
  181. EM_ECOG16 = 176, // Cyan Technology eCOG16
  182. EM_CR16 = 177, // National Semiconductor CompactRISC CR16 16-bit
  183. EM_ETPU = 178, // Freescale Extended Time Processing
  184. EM_SLE9X = 179, // Infineon Technologies SLE9X
  185. EM_L10M = 180, // Intel
  186. EM_K10M = 181, // Intel
  187. // reserved(Intel)
  188. EM_AARCH64 = 183, // ARM 64-bit architecture
  189. // reserved(ARM)
  190. EM_AVR32 = 185, // Atmel Corporation 32-bit microprocessor
  191. EM_STM8 = 186, // STMicroeletronics STM8 8-bit
  192. EM_TILE64 = 187, // Tilera TILE64 multicore architecture
  193. EM_TILEPRO = 188, // Tilera TILEPro multicore architecture
  194. EM_MICROBLAZE = 189, // Xilinx MicroBlaze 32-bit RISC soft processor
  195. EM_CUDA = 190, // NVIDIA CUDA
  196. EM_TILEGX = 191, // Tilera TILE-Gx multicore architecture
  197. EM_CLOUDSHIELD = 192, // CloudShield architecture
  198. EM_COREA_1ST = 193, // KIPO-KAIST Core-A 1st generation processor
  199. EM_COREA_2ND = 194, // KIPO-KAIST Core-A 2nd generation processor
  200. EM_ARC_COMPACT2 = 195, // Synopsys ARCompact
  201. EM_OPEN8 = 196, // Open8 8-bit RISC soft processor
  202. EM_RL78 = 197, // Renesas RL78
  203. EM_VIDEOCORE5 = 198, // Broadcom VideoCore V
  204. EM_78KOR = 199, // Renesas 78KOR
  205. EM_56800EX = 200, // Freescale 56800EX Digital Signal Controller
  206. EM_BA1 = 201, // Beyond BA1 CPU
  207. EM_BA2 = 202, // Beyond BA2 CPU
  208. EM_XCORE = 203, // XMOS xCORE processor
  209. EM_MCHP_PIC = 204, // Microchip 8-bit PIC(r)
  210. // reserved(Intel)
  211. EM_KM32 = 210, // KM211 KM32 32-bit
  212. EM_KMX32 = 211, // KM211 KMX32 32-bit
  213. EM_KMX16 = 212, // KM211 KMX16 16-bit
  214. EM_KMX8 = 213, // KM211 KMX8 8-bit
  215. EM_KVARC = 214, // KM211 KVARC
  216. EM_CDP = 215, // Paneve CDP architecture
  217. EM_COGE = 216, // Cognitive Smart Memory
  218. EM_COOL = 217, // Bluechip Systems
  219. EM_NORC = 218, // Nanoradio Optimized
  220. EM_CSR_KALIMBA = 219, // CSR Kalimba architecture
  221. EM_Z80 = 220, // Zilog
  222. EM_VISIUM = 221, // Controls and Data Services VISIUMcore
  223. EM_FT32 = 222, // FTDI Chip FT32 high performance 32-bit RISC
  224. EM_MOXIE = 223, // Moxie processor
  225. EM_AMDGPU = 224, // AMD GPU
  226. EM_RISCV = 243, // Berkeley RISC-V
  227. PF_X = 0x1, // Execute permission
  228. PF_W = 0x2, // Write permission
  229. PF_R = 0x4, // Read permission
  230. };
  231. struct Elf64_Ehdr {
  232. uint8_t e_ident[16]; /* ELF identification */
  233. uint8_t e_type[2]; /* Object file type */
  234. uint8_t e_machine[2]; /* Machine type */
  235. uint8_t e_version[4]; /* Object file version */
  236. uint8_t e_entry[8]; /* Entry point address */
  237. uint8_t e_phoff[8]; /* Program header offset */
  238. uint8_t e_shoff[8]; /* Section header offset */
  239. uint8_t e_flags[4]; /* Processor-specific flags */
  240. uint8_t e_ehsize[2]; /* ELF header size */
  241. uint8_t e_phentsize[2]; /* Size of program header entry */
  242. uint8_t e_phnum[2]; /* Number of program header entries */
  243. uint8_t e_shentsize[2]; /* Size of section header entry */
  244. uint8_t e_shnum[2]; /* Number of section header entries */
  245. uint8_t e_shstrndx[2]; /* Section name string table index */
  246. };
  247. struct Elf64_Phdr {
  248. uint8_t p_type[4]; /* Type of segment */
  249. uint8_t p_flags[4]; /* Segment attributes */
  250. uint8_t p_offset[8]; /* Offset in file */
  251. uint8_t p_vaddr[8]; /* Virtual address in memory */
  252. uint8_t p_paddr[8]; /* Reserved */
  253. uint8_t p_filesz[8]; /* Size of segment in file */
  254. uint8_t p_memsz[8]; /* Size of segment in memory */
  255. uint8_t p_align[8]; /* Alignment of segment */
  256. };
  257. static struct {
  258. char *mach;
  259. int e_machine;
  260. } elfmachs[] = {
  261. {"amd64", EM_X86_64},
  262. {"arm64", EM_AARCH64},
  263. {"power64", EM_PPC64},
  264. };
  265. static int
  266. ispow2(uintptr_t a)
  267. {
  268. return ((a != 0) && (a & (a-1)) == 0);
  269. }
  270. static int
  271. overlap(uintptr_t a0, uintptr_t aend, uintptr_t b0, uintptr_t bend)
  272. {
  273. uint64_t max0, minend;
  274. max0 = a0 > b0 ? a0 : b0;
  275. minend = aend < bend ? aend : bend;
  276. return max0 < minend;
  277. }
  278. /*
  279. * return the number of ldsegs in rp
  280. */
  281. int
  282. elf64ldseg(Chan *c, uintptr_t *entryp, Ldseg **rp, char *mach, uint32_t minpgsz)
  283. {
  284. Proc *up = externup();
  285. Elf64_Ehdr ehdr;
  286. uint16_t (*get16)(uint8_t *);
  287. uint32_t (*get32)(uint8_t *);
  288. uint64_t (*get64)(uint8_t *);
  289. uint8_t *phbuf, *phend;
  290. uint8_t *fp;
  291. Ldseg *ldseg;
  292. uint64_t entry;
  293. int i, j, si;
  294. entry = 0;
  295. phbuf = nil;
  296. ldseg = nil;
  297. si = 0;
  298. if(waserror()){
  299. if(ldseg != nil)
  300. free(ldseg);
  301. if(phbuf != nil)
  302. free(phbuf);
  303. nexterror();
  304. }
  305. if(c->dev->read(c, &ehdr, sizeof ehdr, 0) != sizeof ehdr){
  306. print("elf64ldseg: too short for header\n");
  307. goto done; // too short to be elf but could be something else
  308. }
  309. fp = ehdr.e_ident;
  310. if(fp[EI_MAG0] == '\x7f' && fp[EI_MAG1] == 'E' && fp[EI_MAG2] == 'L' && fp[EI_MAG3] == 'F'){
  311. if(fp[EI_DATA] == ELFDATA2LSB){
  312. get16 = get16le;
  313. get32 = get32le;
  314. get64 = get64le;
  315. } else if(fp[EI_DATA] == ELFDATA2MSB){
  316. get16 = get16be;
  317. get32 = get32be;
  318. get64 = get64be;
  319. }
  320. if(fp[EI_CLASS] == ELFCLASS64){
  321. int64_t phoff;
  322. uint32_t phnum, phentsize;
  323. uint16_t e_machine;
  324. e_machine = get16(ehdr.e_machine);
  325. if(mach != nil){
  326. for(i = 0; i < nelem(elfmachs); i++)
  327. if(elfmachs[i].e_machine == e_machine && !strcmp(mach, elfmachs[i].mach))
  328. break;
  329. if(i == nelem(elfmachs)){
  330. print("elf64ldseg: e_machine %d incorrect for host %s\n", e_machine, mach);
  331. error(Ebadexec);
  332. }
  333. }
  334. entry = get64(ehdr.e_entry);
  335. phoff = get16(ehdr.e_phoff);
  336. phnum = get16(ehdr.e_phnum);
  337. phentsize = get16(ehdr.e_phentsize);
  338. if(phentsize*phnum > minpgsz){
  339. print("elf64ldseg: phentsize %d phnum %d exceeds page size %d\n", phentsize, phnum, minpgsz);
  340. error(Ebadexec);
  341. }
  342. phbuf = malloc(phentsize*phnum);
  343. if(phbuf == nil){
  344. print("elf64ldseg: malloc fail\n");
  345. error(Ebadexec);
  346. }
  347. if(c->dev->read(c, phbuf, phentsize*phnum, phoff) != phentsize*phnum){
  348. print("elf64ldseg: read program header fail\n");
  349. error(Ebadexec);
  350. }
  351. si = 0;
  352. phend = phbuf + phentsize*phnum;
  353. for(fp = phbuf; fp < phend; fp += phentsize){
  354. Elf64_Phdr *phdr;
  355. phdr = (Elf64_Phdr*)fp;
  356. if(get32(phdr->p_type) == PT_LOAD)
  357. si++;
  358. }
  359. ldseg = malloc(si * sizeof ldseg[0]);
  360. if(ldseg == nil){
  361. print("elf64ldseg: malloc fail\n");
  362. error(Ebadexec);
  363. }
  364. si = 0;
  365. for(fp = phbuf; fp < phend; fp += phentsize){
  366. Elf64_Phdr *phdr;
  367. phdr = (Elf64_Phdr*)fp;
  368. if(get32(phdr->p_type) == PT_LOAD){
  369. uint64_t offset, vaddr, align, filesz, memsz;
  370. uint32_t flags;
  371. flags = get32(phdr->p_flags); /* Segment attributes */
  372. offset = get64(phdr->p_offset); /* Offset in file */
  373. vaddr = get64(phdr->p_vaddr); /* Virtual address in memory */
  374. filesz = get64(phdr->p_filesz); /* Size of segment in file */
  375. memsz = get64(phdr->p_memsz); /* Size of segment in memory */
  376. align = get64(phdr->p_align); /* Alignment of segment */
  377. ldseg[si].type = SG_LOAD;
  378. if((flags & PF_R) != 0)
  379. ldseg[si].type |= SG_READ;
  380. if((flags & PF_W) != 0)
  381. ldseg[si].type |= SG_WRITE;
  382. if((flags & PF_X) != 0)
  383. ldseg[si].type |= SG_EXEC;
  384. if(memsz < filesz){
  385. print("elf64ldseg: memsz %d < filesz %d\n", memsz, filesz);
  386. error(Ebadexec);
  387. }
  388. if(!ispow2(align)){
  389. print("elf64ldseg: align 0x%x not a power of 2\n", align);
  390. error(Ebadexec);
  391. }
  392. if(align < minpgsz){
  393. print("elf64ldseg: align 0x%x < minpgsz 0x%x\n", align, minpgsz);
  394. error(Ebadexec);
  395. }
  396. if(offset & (align-1) != vaddr & (align-1)){
  397. print("elf64ldseg: va offset 0x%x != file offset 0x%x (align 0x%x)\n",
  398. offset & (align-1),
  399. vaddr & (align-1),
  400. align
  401. );
  402. error(Ebadexec);
  403. }
  404. ldseg[si].pgsz = align;
  405. ldseg[si].memsz = memsz;
  406. ldseg[si].filesz = filesz;
  407. ldseg[si].pg0fileoff = offset & ~(align-1);
  408. ldseg[si].pg0vaddr = vaddr & ~(align-1);
  409. ldseg[si].pg0off = offset & (align-1);
  410. si++;
  411. }
  412. }
  413. for(i = 0; i < si; i++){
  414. for(j = 0; j < si; j++){
  415. if(i != j){
  416. Ldseg *lda, *ldb;
  417. lda = ldseg+i;
  418. ldb = ldseg+j;
  419. if(overlap(
  420. lda->pg0vaddr, lda->pg0vaddr + lda->pg0off + lda->memsz,
  421. ldb->pg0vaddr, ldb->pg0vaddr + ldb->pg0off + ldb->memsz
  422. )){
  423. print("elf64ldseg: load segs %p:%p and %p:%p ovelap\n",
  424. lda->pg0vaddr, lda->pg0vaddr + lda->pg0off + lda->memsz,
  425. ldb->pg0vaddr, ldb->pg0vaddr + ldb->pg0off + ldb->memsz
  426. );
  427. error(Ebadexec);
  428. }
  429. }
  430. }
  431. }
  432. } else {
  433. print("elf64ldseg: not elfclass64\n");
  434. error(Ebadexec);
  435. }
  436. }
  437. done:
  438. if(phbuf != nil)
  439. free(phbuf);
  440. if(rp != nil){
  441. *rp = ldseg;
  442. } else if(ldseg != nil){
  443. free(ldseg);
  444. }
  445. if(entryp != nil)
  446. *entryp = entry;
  447. poperror();
  448. return si;
  449. }