json_value.asm: No such file or directory

本文介绍了解决编译时遇到的错误——无法打开文件'json_writer.asm'的方法。主要提供了两种解决方案:一是调整jsoncpp项目的设置,禁用全程序优化;二是修改项目的汇编程序输出设置为无列表。

转自: http://blog.youkuaiyun.com/sdcxyz/article/details/11983657


链接提示:无法打开编译器生成的文件:“../../build/vs71/release/lib_json\json_writer.asm


解决方法:1:修改jsoncpp的项目设置  配置属性---全程序优化 为无全程序优化

              或者2:修改菜单---项目--属性---配置属性---c/c++---输出文件---汇编程序输出:无列表 


PS E:\stm\tim_servo> ninja -C build ninja: Entering directory `build' [1/6] Building C object CMakeFiles/tim_servo.dir/Core/Src/syscalls.c.obj FAILED: [code=1] CMakeFiles/tim_servo.dir/Core/Src/syscalls.c.obj C:\msys64\ucrt64\bin\gcc.exe -DDEBUG -DSTM32F103xB -DUSE_HAL_DRIVER -IE:/stm/tim_servo/cmake/stm32cubemx/../../Core/Inc -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/CMSIS/Device/ST/STM32F1xx/Include -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/CMSIS/Include -std=gnu11 -MD -MT CMakeFiles/tim_servo.dir/Core/Src/syscalls.c.obj -MF CMakeFiles\tim_servo.dir\Core\Src\syscalls.c.obj.d -o CMakeFiles/tim_servo.dir/Core/Src/syscalls.c.obj -c E:/stm/tim_servo/Core/Src/syscalls.c E:/stm/tim_servo/Core/Src/syscalls.c:31:10: fatal error: sys/times.h: No such file or directory 31 | #include <sys/times.h> | ^~~~~~~~~~~~~ compilation terminated. [2/6] Building ASM object CMakeFiles/tim_servo.dir/startup_stm32f103xb.s.obj FAILED: [code=1] CMakeFiles/tim_servo.dir/startup_stm32f103xb.s.obj C:\msys64\ucrt64\bin\gcc.exe -DDEBUG -DSTM32F103xB -DUSE_HAL_DRIVER -IE:/stm/tim_servo/cmake/stm32cubemx/../../Core/Inc -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/CMSIS/Device/ST/STM32F1xx/Include -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/CMSIS/Include -g -MD -MT CMakeFiles/tim_servo.dir/startup_stm32f103xb.s.obj -MF CMakeFiles\tim_servo.dir\startup_stm32f103xb.s.obj.d -o CMakeFiles/tim_servo.dir/startup_stm32f103xb.s.obj -c E:/stm/tim_servo/startup_stm32f103xb.s E:/stm/tim_servo/startup_stm32f103xb.s: Assembler messages: E:/stm/tim_servo/startup_stm32f103xb.s:28: Error: unknown pseudo-op: `.syntax' E:/stm/tim_servo/startup_stm32f103xb.s:29: Error: unknown pseudo-op: `.cpu' E:/stm/tim_servo/startup_stm32f103xb.s:30: Error: unknown pseudo-op: `.fpu' E:/stm/tim_servo/startup_stm32f103xb.s:31: Error: unknown pseudo-op: `.thumb' E:/stm/tim_servo/startup_stm32f103xb.s:59: Warning: .type pseudo-op used outside of .def/.endef: ignored. E:/stm/tim_servo/startup_stm32f103xb.s:59: Error: junk at end of line, first unrecognized character is `R' E:/stm/tim_servo/startup_stm32f103xb.s:63: Error: no such instruction: `bl SystemInit' E:/stm/tim_servo/startup_stm32f103xb.s:66: Error: no such instruction: `ldr r0,=_sdata' E:/stm/tim_servo/startup_stm32f103xb.s:67: Error: no such instruction: `ldr r1,=_edata' E:/stm/tim_servo/startup_stm32f103xb.s:68: Error: no such instruction: `ldr r2,=_sidata' E:/stm/tim_servo/startup_stm32f103xb.s:69: Warning: `r3' is not valid here (expected `(%rsi)') E:/stm/tim_servo/startup_stm32f103xb.s:69: Error: expecting operand after ','; got nothing E:/stm/tim_servo/startup_stm32f103xb.s:70: Error: no such instruction: `b LoopCopyDataInit' E:/stm/tim_servo/startup_stm32f103xb.s:73: Error: no such instruction: `ldr r4,[r2,r3]' E:/stm/tim_servo/startup_stm32f103xb.s:74: Error: missing ']' E:/stm/tim_servo/startup_stm32f103xb.s:74: Error: too many memory references for `str' E:/stm/tim_servo/startup_stm32f103xb.s:75: Error: expecting operand after ','; got nothing E:/stm/tim_servo/startup_stm32f103xb.s:78: Error: too many memory references for `add' E:/stm/tim_servo/startup_stm32f103xb.s:79: Error: operand type mismatch for `cmp' E:/stm/tim_servo/startup_stm32f103xb.s:80: Error: no such instruction: `bcc CopyDataInit' E:/stm/tim_servo/startup_stm32f103xb.s:83: Error: no such instruction: `ldr r2,=_sbss' E:/stm/tim_servo/startup_stm32f103xb.s:84: Error: no such instruction: `ldr r4,=_ebss' E:/stm/tim_servo/startup_stm32f103xb.s:85: Warning: `r3' is not valid here (expected `(%rsi)') E:/stm/tim_servo/startup_stm32f103xb.s:85: Error: expecting operand after ','; got nothing E:/stm/tim_servo/startup_stm32f103xb.s:86: Error: no such instruction: `b LoopFillZerobss' E:/stm/tim_servo/startup_stm32f103xb.s:89: Error: number of operands mismatch for `str' E:/stm/tim_servo/startup_stm32f103xb.s:90: Error: expecting operand after ','; got nothing E:/stm/tim_servo/startup_stm32f103xb.s:93: Error: operand type mismatch for `cmp' E:/stm/tim_servo/startup_stm32f103xb.s:94: Error: no such instruction: `bcc FillZerobss' E:/stm/tim_servo/startup_stm32f103xb.s:97: Error: no such instruction: `bl __libc_init_array' E:/stm/tim_servo/startup_stm32f103xb.s:99: Error: no such instruction: `bl main' E:/stm/tim_servo/startup_stm32f103xb.s:100: Error: no such instruction: `bx lr' E:/stm/tim_servo/startup_stm32f103xb.s:101: Warning: .size pseudo-op used outside of .def/.endef: ignored. E:/stm/tim_servo/startup_stm32f103xb.s:101: Error: junk at end of line, first unrecognized character is `R' E:/stm/tim_servo/startup_stm32f103xb.s:111: Error: junk at end of line, first unrecognized character is `,' E:/stm/tim_servo/startup_stm32f103xb.s:114: Error: no such instruction: `b Infinite_Loop' E:/stm/tim_servo/startup_stm32f103xb.s:115: Warning: .size pseudo-op used outside of .def/.endef: ignored. E:/stm/tim_servo/startup_stm32f103xb.s:115: Error: junk at end of line, first unrecognized character is `D' E:/stm/tim_servo/startup_stm32f103xb.s:123: Error: junk at end of line, first unrecognized character is `,' E:/stm/tim_servo/startup_stm32f103xb.s:124: Warning: .type pseudo-op used outside of .def/.endef: ignored. E:/stm/tim_servo/startup_stm32f103xb.s:124: Error: junk at end of line, first unrecognized character is `g' E:/stm/tim_servo/startup_stm32f103xb.s:125: Warning: .size pseudo-op used outside of .def/.endef: ignored. E:/stm/tim_servo/startup_stm32f103xb.s:125: Error: junk at end of line, first unrecognized character is `g' E:/stm/tim_servo/startup_stm32f103xb.s:196: Warning: value 0xf108f85f truncated to 0xf85f E:/stm/tim_servo/startup_stm32f103xb.s:207: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:209: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:211: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:213: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:215: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:217: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:219: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:221: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:223: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:225: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:227: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:229: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:231: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:233: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:235: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:237: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:239: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:241: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:243: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:245: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:247: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:249: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:251: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:253: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:255: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:257: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:259: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:261: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:263: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:265: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:267: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:269: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:271: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:273: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:275: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:277: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:279: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:281: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:283: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:285: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:287: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:289: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:291: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:293: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:295: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:297: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:299: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:301: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:303: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:305: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:307: Error: unknown pseudo-op: `.thumb_set' E:/stm/tim_servo/startup_stm32f103xb.s:309: Error: unknown pseudo-op: `.thumb_set' [3/6] Building C object CMakeFiles/tim_servo.dir/Core/Src/main.c.obj FAILED: [code=1] CMakeFiles/tim_servo.dir/Core/Src/main.c.obj C:\msys64\ucrt64\bin\gcc.exe -DDEBUG -DSTM32F103xB -DUSE_HAL_DRIVER -IE:/stm/tim_servo/cmake/stm32cubemx/../../Core/Inc -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/CMSIS/Device/ST/STM32F1xx/Include -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/CMSIS/Include -std=gnu11 -MD -MT CMakeFiles/tim_servo.dir/Core/Src/main.c.obj -MF CMakeFiles\tim_servo.dir\Core\Src\main.c.obj.d -o CMakeFiles/tim_servo.dir/Core/Src/main.c.obj -c E:/stm/tim_servo/Core/Src/main.c In file included from E:/stm/tim_servo/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h:131, from E:/stm/tim_servo/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h:130, from E:/stm/tim_servo/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h:29, from E:/stm/tim_servo/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h:27, from E:/stm/tim_servo/Core/Inc/stm32f1xx_hal_conf.h:238, from E:/stm/tim_servo/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h:29, from E:/stm/tim_servo/Core/Inc/main.h:30, from E:/stm/tim_servo/Core/Src/main.c:20: E:/stm/tim_servo/Drivers/CMSIS/Include/core_cm3.h: In function '__NVIC_SetVector': E:/stm/tim_servo/Drivers/CMSIS/Include/core_cm3.h:1738:23: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 1738 | uint32_t *vectors = (uint32_t *)SCB->VTOR; | ^ E:/stm/tim_servo/Drivers/CMSIS/Include/core_cm3.h: In function '__NVIC_GetVector': E:/stm/tim_servo/Drivers/CMSIS/Include/core_cm3.h:1753:23: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 1753 | uint32_t *vectors = (uint32_t *)SCB->VTOR; | ^ C:\Users\Yeah\AppData\Local\Temp\ccIGZrQh.s: Assembler messages: C:\Users\Yeah\AppData\Local\Temp\ccIGZrQh.s:139: Error: no such instruction: `cpsid i' [4/6] Building C object cmake/stm32cubemx/CMakeFiles/STM32_Drivers.dir/__/__/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c.obj FAILED: [code=1] cmake/stm32cubemx/CMakeFiles/STM32_Drivers.dir/__/__/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c.obj C:\msys64\ucrt64\bin\gcc.exe -DDEBUG -DSTM32F103xB -DUSE_HAL_DRIVER -IE:/stm/tim_servo/cmake/stm32cubemx/../../Core/Inc -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/CMSIS/Device/ST/STM32F1xx/Include -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/CMSIS/Include -std=gnu11 -MD -MT cmake/stm32cubemx/CMakeFiles/STM32_Drivers.dir/__/__/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c.obj -MF cmake\stm32cubemx\CMakeFiles\STM32_Drivers.dir\__\__\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c.obj.d -o cmake/stm32cubemx/CMakeFiles/STM32_Drivers.dir/__/__/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c.obj -c E:/stm/tim_servo/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c In file included from E:/stm/tim_servo/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h:131, from E:/stm/tim_servo/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h:130, from E:/stm/tim_servo/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h:29, from E:/stm/tim_servo/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h:27, from E:/stm/tim_servo/Core/Inc/stm32f1xx_hal_conf.h:238, from E:/stm/tim_servo/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h:29, from E:/stm/tim_servo/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c:82: E:/stm/tim_servo/Drivers/CMSIS/Include/core_cm3.h: In function '__NVIC_SetVector': E:/stm/tim_servo/Drivers/CMSIS/Include/core_cm3.h:1738:23: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 1738 | uint32_t *vectors = (uint32_t *)SCB->VTOR; | ^ E:/stm/tim_servo/Drivers/CMSIS/Include/core_cm3.h: In function '__NVIC_GetVector': E:/stm/tim_servo/Drivers/CMSIS/Include/core_cm3.h:1753:23: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 1753 | uint32_t *vectors = (uint32_t *)SCB->VTOR; | ^ C:\Users\Yeah\AppData\Local\Temp\ccLF5hmc.s: Assembler messages: C:\Users\Yeah\AppData\Local\Temp\ccLF5hmc.s:105: Error: number of operands mismatch for `ds' C:\Users\Yeah\AppData\Local\Temp\ccLF5hmc.s:111: Error: no such instruction: `isb 0xF' C:\Users\Yeah\AppData\Local\Temp\ccLF5hmc.s:445: Error: number of operands mismatch for `ds' C:\Users\Yeah\AppData\Local\Temp\ccLF5hmc.s:458: Error: number of operands mismatch for `ds' [5/6] Building C object cmake/stm32cubemx/CMakeFiles/STM32_Drivers.dir/__/__/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c.obj FAILED: [code=1] cmake/stm32cubemx/CMakeFiles/STM32_Drivers.dir/__/__/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c.obj C:\msys64\ucrt64\bin\gcc.exe -DDEBUG -DSTM32F103xB -DUSE_HAL_DRIVER -IE:/stm/tim_servo/cmake/stm32cubemx/../../Core/Inc -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/CMSIS/Device/ST/STM32F1xx/Include -IE:/stm/tim_servo/cmake/stm32cubemx/../../Drivers/CMSIS/Include -std=gnu11 -MD -MT cmake/stm32cubemx/CMakeFiles/STM32_Drivers.dir/__/__/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c.obj -MF cmake\stm32cubemx\CMakeFiles\STM32_Drivers.dir\__\__\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c.obj.d -o cmake/stm32cubemx/CMakeFiles/STM32_Drivers.dir/__/__/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c.obj -c E:/stm/tim_servo/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c In file included from E:/stm/tim_servo/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h:131, from E:/stm/tim_servo/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h:130, from E:/stm/tim_servo/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h:29, from E:/stm/tim_servo/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h:27, from E:/stm/tim_servo/Core/Inc/stm32f1xx_hal_conf.h:238, from E:/stm/tim_servo/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h:29, from E:/stm/tim_servo/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c:26: E:/stm/tim_servo/Drivers/CMSIS/Include/core_cm3.h: In function '__NVIC_SetVector': E:/stm/tim_servo/Drivers/CMSIS/Include/core_cm3.h:1738:23: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 1738 | uint32_t *vectors = (uint32_t *)SCB->VTOR; | ^ E:/stm/tim_servo/Drivers/CMSIS/Include/core_cm3.h: In function '__NVIC_GetVector': E:/stm/tim_servo/Drivers/CMSIS/Include/core_cm3.h:1753:23: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 1753 | uint32_t *vectors = (uint32_t *)SCB->VTOR; | ^ E:/stm/tim_servo/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c: In function 'HAL_PWR_EnableWakeUpPin': E:/stm/tim_servo/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c:386:4: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 386 | *(__IO uint32_t *) CSR_EWUP_BB(WakeUpPinx) = (uint32_t)ENABLE; | ^ E:/stm/tim_servo/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c: In function 'HAL_PWR_DisableWakeUpPin': E:/stm/tim_servo/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c:401:4: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 401 | *(__IO uint32_t *) CSR_EWUP_BB(WakeUpPinx) = (uint32_t)DISABLE; | ^ C:\Users\Yeah\AppData\Local\Temp\ccnxrD4a.s: Assembler messages: C:\Users\Yeah\AppData\Local\Temp\ccnxrD4a.s:13: Error: no such instruction: `wfe' C:\Users\Yeah\AppData\Local\Temp\ccnxrD4a.s:304: Error: no such instruction: `wfi' C:\Users\Yeah\AppData\Local\Temp\ccnxrD4a.s:311: Error: no such instruction: `sev' C:\Users\Yeah\AppData\Local\Temp\ccnxrD4a.s:314: Error: no such instruction: `wfe' C:\Users\Yeah\AppData\Local\Temp\ccnxrD4a.s:317: Error: no such instruction: `wfe' C:\Users\Yeah\AppData\Local\Temp\ccnxrD4a.s:359: Error: no such instruction: `wfi' C:\Users\Yeah\AppData\Local\Temp\ccnxrD4a.s:366: Error: no such instruction: `sev' C:\Users\Yeah\AppData\Local\Temp\ccnxrD4a.s:403: Error: no such instruction: `wfi' ninja: build stopped: subcommand failed.如何解决
11-15
/* * linux/fs/open.c * * Copyright (C) 1991, 1992 Linus Torvalds */ #include <linux/string.h> #include <linux/mm.h> #include <linux/file.h> #include <linux/fdtable.h> #include <linux/fsnotify.h> #include <linux/module.h> #include <linux/tty.h> #include <linux/namei.h> #include <linux/backing-dev.h> #include <linux/capability.h> #include <linux/securebits.h> #include <linux/security.h> #include <linux/mount.h> #include <linux/fcntl.h> #include <linux/slab.h> #include <asm/uaccess.h> #include <linux/fs.h> #include <linux/personality.h> #include <linux/pagemap.h> #include <linux/syscalls.h> #include <linux/rcupdate.h> #include <linux/audit.h> #include <linux/falloc.h> #include <linux/fs_struct.h> #include <linux/ima.h> #include <linux/dnotify.h> #include <linux/compat.h> #include "internal.h" int do_truncate2(struct vfsmount *mnt, struct dentry *dentry, loff_t length, unsigned int time_attrs, struct file *filp) { int ret; struct iattr newattrs; /* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */ if (length < 0) return -EINVAL; newattrs.ia_size = length; newattrs.ia_valid = ATTR_SIZE | time_attrs; if (filp) { newattrs.ia_file = filp; newattrs.ia_valid |= ATTR_FILE; } /* Remove suid, sgid, and file capabilities on truncate too */ ret = dentry_needs_remove_privs(dentry); if (ret < 0) return ret; if (ret) newattrs.ia_valid |= ret | ATTR_FORCE; mutex_lock(&dentry->d_inode->i_mutex); /* Note any delegations or leases have already been broken: */ ret = notify_change2(mnt, dentry, &newattrs, NULL); mutex_unlock(&dentry->d_inode->i_mutex); return ret; } int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, struct file *filp) { return do_truncate2(NULL, dentry, length, time_attrs, filp); } long vfs_truncate(struct path *path, loff_t length) { struct inode *inode; struct vfsmount *mnt; long error; inode = path->dentry->d_inode; mnt = path->mnt; /* For directories it's -EISDIR, for other non-regulars - -EINVAL */ if (S_ISDIR(inode->i_mode)) return -EISDIR; if (!S_ISREG(inode->i_mode)) return -EINVAL; error = mnt_want_write(path->mnt); if (error) goto out; error = inode_permission2(mnt, inode, MAY_WRITE); if (error) goto mnt_drop_write_and_out; error = -EPERM; if (IS_APPEND(inode)) goto mnt_drop_write_and_out; error = get_write_access(inode); if (error) goto mnt_drop_write_and_out; /* * Make sure that there are no leases. get_write_access() protects * against the truncate racing with a lease-granting setlease(). */ error = break_lease(inode, O_WRONLY); if (error) goto put_write_and_out; error = locks_verify_truncate(inode, NULL, length); if (!error) error = security_path_truncate(path); if (!error) error = do_truncate2(mnt, path->dentry, length, 0, NULL); put_write_and_out: put_write_access(inode); mnt_drop_write_and_out: mnt_drop_write(path->mnt); out: return error; } EXPORT_SYMBOL_GPL(vfs_truncate); static long do_sys_truncate(const char __user *pathname, loff_t length) { unsigned int lookup_flags = LOOKUP_FOLLOW; struct path path; int error; if (length < 0) /* sorry, but loff_t says... */ return -EINVAL; retry: error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); if (!error) { error = vfs_truncate(&path, length); path_put(&path); } if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; goto retry; } return error; } SYSCALL_DEFINE2(truncate, const char __user *, path, long, length) { return do_sys_truncate(path, length); } #ifdef CONFIG_COMPAT COMPAT_SYSCALL_DEFINE2(truncate, const char __user *, path, compat_off_t, length) { return do_sys_truncate(path, length); } #endif static long do_sys_ftruncate(unsigned int fd, loff_t length, int small) { struct inode *inode; struct dentry *dentry; struct vfsmount *mnt; struct fd f; int error; error = -EINVAL; if (length < 0) goto out; error = -EBADF; f = fdget(fd); if (!f.file) goto out; /* explicitly opened as large or we are on 64-bit box */ if (f.file->f_flags & O_LARGEFILE) small = 0; dentry = f.file->f_path.dentry; mnt = f.file->f_path.mnt; inode = dentry->d_inode; error = -EINVAL; if (!S_ISREG(inode->i_mode) || !(f.file->f_mode & FMODE_WRITE)) goto out_putf; error = -EINVAL; /* Cannot ftruncate over 2^31 bytes without large file support */ if (small && length > MAX_NON_LFS) goto out_putf; error = -EPERM; if (IS_APPEND(inode)) goto out_putf; sb_start_write(inode->i_sb); error = locks_verify_truncate(inode, f.file, length); if (!error) error = security_path_truncate(&f.file->f_path); if (!error) error = do_truncate2(mnt, dentry, length, ATTR_MTIME|ATTR_CTIME, f.file); sb_end_write(inode->i_sb); out_putf: fdput(f); out: return error; } SYSCALL_DEFINE2(ftruncate, unsigned int, fd, unsigned long, length) { return do_sys_ftruncate(fd, length, 1); } #ifdef CONFIG_COMPAT COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_ulong_t, length) { return do_sys_ftruncate(fd, length, 1); } #endif /* LFS versions of truncate are only needed on 32 bit machines */ #if BITS_PER_LONG == 32 SYSCALL_DEFINE2(truncate64, const char __user *, path, loff_t, length) { return do_sys_truncate(path, length); } SYSCALL_DEFINE2(ftruncate64, unsigned int, fd, loff_t, length) { return do_sys_ftruncate(fd, length, 0); } #endif /* BITS_PER_LONG == 32 */ int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len) { struct inode *inode = file_inode(file); long ret; if (offset < 0 || len <= 0) return -EINVAL; /* Return error if mode is not supported */ if (mode & ~FALLOC_FL_SUPPORTED_MASK) return -EOPNOTSUPP; /* Punch hole and zero range are mutually exclusive */ if ((mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) == (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) return -EOPNOTSUPP; /* Punch hole must have keep size set */ if ((mode & FALLOC_FL_PUNCH_HOLE) && !(mode & FALLOC_FL_KEEP_SIZE)) return -EOPNOTSUPP; /* Collapse range should only be used exclusively. */ if ((mode & FALLOC_FL_COLLAPSE_RANGE) && (mode & ~FALLOC_FL_COLLAPSE_RANGE)) return -EINVAL; /* Insert range should only be used exclusively. */ if ((mode & FALLOC_FL_INSERT_RANGE) && (mode & ~FALLOC_FL_INSERT_RANGE)) return -EINVAL; if (!(file->f_mode & FMODE_WRITE)) return -EBADF; /* * We can only allow pure fallocate on append only files */ if ((mode & ~FALLOC_FL_KEEP_SIZE) && IS_APPEND(inode)) return -EPERM; if (IS_IMMUTABLE(inode)) return -EPERM; /* * We cannot allow any fallocate operation on an active swapfile */ if (IS_SWAPFILE(inode)) return -ETXTBSY; /* * Revalidate the write permissions, in case security policy has * changed since the files were opened. */ ret = security_file_permission(file, MAY_WRITE); if (ret) return ret; if (S_ISFIFO(inode->i_mode)) return -ESPIPE; /* * Let individual file system decide if it supports preallocation * for directories or not. */ if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) return -ENODEV; /* Check for wrap through zero too */ if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0)) return -EFBIG; if (!file->f_op->fallocate) return -EOPNOTSUPP; sb_start_write(inode->i_sb); ret = file->f_op->fallocate(file, mode, offset, len); /* * Create inotify and fanotify events. * * To keep the logic simple always create events if fallocate succeeds. * This implies that events are even created if the file size remains * unchanged, e.g. when using flag FALLOC_FL_KEEP_SIZE. */ if (ret == 0) fsnotify_modify(file); sb_end_write(inode->i_sb); return ret; } EXPORT_SYMBOL_GPL(vfs_fallocate); SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) { struct fd f = fdget(fd); int error = -EBADF; if (f.file) { error = vfs_fallocate(f.file, mode, offset, len); fdput(f); } return error; } /* * access() needs to use the real uid/gid, not the effective uid/gid. * We do this by temporarily clearing all FS-related capabilities and * switching the fsuid/fsgid around to the real ones. */ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) { const struct cred *old_cred; struct cred *override_cred; struct path path; struct inode *inode; struct vfsmount *mnt; int res; unsigned int lookup_flags = LOOKUP_FOLLOW; if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ return -EINVAL; override_cred = prepare_creds(); if (!override_cred) return -ENOMEM; override_cred->fsuid = override_cred->uid; override_cred->fsgid = override_cred->gid; if (!issecure(SECURE_NO_SETUID_FIXUP)) { /* Clear the capabilities if we switch to a non-root user */ kuid_t root_uid = make_kuid(override_cred->user_ns, 0); if (!uid_eq(override_cred->uid, root_uid)) cap_clear(override_cred->cap_effective); else override_cred->cap_effective = override_cred->cap_permitted; } /* * The new set of credentials can *only* be used in * task-synchronous circumstances, and does not need * RCU freeing, unless somebody then takes a separate * reference to it. * * NOTE! This is _only_ true because this credential * is used purely for override_creds() that installs * it as the subjective cred. Other threads will be * accessing ->real_cred, not the subjective cred. * * If somebody _does_ make a copy of this (using the * 'get_current_cred()' function), that will clear the * non_rcu field, because now that other user may be * expecting RCU freeing. But normal thread-synchronous * cred accesses will keep things non-RCY. */ override_cred->non_rcu = 1; old_cred = override_creds(override_cred); retry: res = user_path_at(dfd, filename, lookup_flags, &path); if (res) goto out; inode = d_backing_inode(path.dentry); mnt = path.mnt; if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) { /* * MAY_EXEC on regular files is denied if the fs is mounted * with the "noexec" flag. */ res = -EACCES; if (path_noexec(&path)) goto out_path_release; } res = inode_permission2(mnt, inode, mode | MAY_ACCESS); /* SuS v2 requires we report a read only fs too */ if (res || !(mode & S_IWOTH) || special_file(inode->i_mode)) goto out_path_release; /* * This is a rare case where using __mnt_is_readonly() * is OK without a mnt_want/drop_write() pair. Since * no actual write to the fs is performed here, we do * not need to telegraph to that to anyone. * * By doing this, we accept that this access is * inherently racy and know that the fs may change * state before we even see this result. */ if (__mnt_is_readonly(path.mnt)) res = -EROFS; out_path_release: path_put(&path); if (retry_estale(res, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; goto retry; } out: revert_creds(old_cred); put_cred(override_cred); return res; } SYSCALL_DEFINE2(access, const char __user *, filename, int, mode) { return sys_faccessat(AT_FDCWD, filename, mode); } SYSCALL_DEFINE1(chdir, const char __user *, filename) { struct path path; int error; unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY; retry: error = user_path_at(AT_FDCWD, filename, lookup_flags, &path); if (error) goto out; error = inode_permission2(path.mnt, path.dentry->d_inode, MAY_EXEC | MAY_CHDIR); if (error) goto dput_and_out; set_fs_pwd(current->fs, &path); dput_and_out: path_put(&path); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; goto retry; } out: return error; } SYSCALL_DEFINE1(fchdir, unsigned int, fd) { struct fd f = fdget_raw(fd); struct inode *inode; struct vfsmount *mnt; int error = -EBADF; error = -EBADF; if (!f.file) goto out; inode = file_inode(f.file); mnt = f.file->f_path.mnt; error = -ENOTDIR; if (!S_ISDIR(inode->i_mode)) goto out_putf; error = inode_permission2(mnt, inode, MAY_EXEC | MAY_CHDIR); if (!error) set_fs_pwd(current->fs, &f.file->f_path); out_putf: fdput(f); out: return error; } SYSCALL_DEFINE1(chroot, const char __user *, filename) { struct path path; int error; unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY; retry: error = user_path_at(AT_FDCWD, filename, lookup_flags, &path); if (error) goto out; error = inode_permission2(path.mnt, path.dentry->d_inode, MAY_EXEC | MAY_CHDIR); if (error) goto dput_and_out; error = -EPERM; if (!ns_capable(current_user_ns(), CAP_SYS_CHROOT)) goto dput_and_out; error = security_path_chroot(&path); if (error) goto dput_and_out; set_fs_root(current->fs, &path); error = 0; dput_and_out: path_put(&path); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; goto retry; } out: return error; } static int chmod_common(struct path *path, umode_t mode) { struct inode *inode = path->dentry->d_inode; struct inode *delegated_inode = NULL; struct iattr newattrs; int error; error = mnt_want_write(path->mnt); if (error) return error; retry_deleg: mutex_lock(&inode->i_mutex); error = security_path_chmod(path, mode); if (error) goto out_unlock; newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; error = notify_change2(path->mnt, path->dentry, &newattrs, &delegated_inode); out_unlock: mutex_unlock(&inode->i_mutex); if (delegated_inode) { error = break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; } mnt_drop_write(path->mnt); return error; } SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode) { struct fd f = fdget(fd); int err = -EBADF; if (f.file) { audit_file(f.file); err = chmod_common(&f.file->f_path, mode); fdput(f); } return err; } SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode) { struct path path; int error; unsigned int lookup_flags = LOOKUP_FOLLOW; retry: error = user_path_at(dfd, filename, lookup_flags, &path); if (!error) { error = chmod_common(&path, mode); path_put(&path); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; goto retry; } } return error; } SYSCALL_DEFINE2(chmod, const char __user *, filename, umode_t, mode) { return sys_fchmodat(AT_FDCWD, filename, mode); } static int chown_common(struct path *path, uid_t user, gid_t group) { struct inode *inode = path->dentry->d_inode; struct inode *delegated_inode = NULL; int error; struct iattr newattrs; kuid_t uid; kgid_t gid; uid = make_kuid(current_user_ns(), user); gid = make_kgid(current_user_ns(), group); retry_deleg: newattrs.ia_valid = ATTR_CTIME; if (user != (uid_t) -1) { if (!uid_valid(uid)) return -EINVAL; newattrs.ia_valid |= ATTR_UID; newattrs.ia_uid = uid; } if (group != (gid_t) -1) { if (!gid_valid(gid)) return -EINVAL; newattrs.ia_valid |= ATTR_GID; newattrs.ia_gid = gid; } if (!S_ISDIR(inode->i_mode)) newattrs.ia_valid |= ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; mutex_lock(&inode->i_mutex); error = security_path_chown(path, uid, gid); if (!error) error = notify_change2(path->mnt, path->dentry, &newattrs, &delegated_inode); mutex_unlock(&inode->i_mutex); if (delegated_inode) { error = break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; } return error; } SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user, gid_t, group, int, flag) { struct path path; int error = -EINVAL; int lookup_flags; if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0) goto out; lookup_flags = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW; if (flag & AT_EMPTY_PATH) lookup_flags |= LOOKUP_EMPTY; retry: error = user_path_at(dfd, filename, lookup_flags, &path); if (error) goto out; error = mnt_want_write(path.mnt); if (error) goto out_release; error = chown_common(&path, user, group); mnt_drop_write(path.mnt); out_release: path_put(&path); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; goto retry; } out: return error; } SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group) { return sys_fchownat(AT_FDCWD, filename, user, group, 0); } SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group) { return sys_fchownat(AT_FDCWD, filename, user, group, AT_SYMLINK_NOFOLLOW); } SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) { struct fd f = fdget(fd); int error = -EBADF; if (!f.file) goto out; error = mnt_want_write_file(f.file); if (error) goto out_fput; audit_file(f.file); error = chown_common(&f.file->f_path, user, group); mnt_drop_write_file(f.file); out_fput: fdput(f); out: return error; } int open_check_o_direct(struct file *f) { /* NB: we're sure to have correct a_ops only after f_op->open */ if (f->f_flags & O_DIRECT) { if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO) return -EINVAL; } return 0; } static int do_dentry_open(struct file *f, struct inode *inode, int (*open)(struct inode *, struct file *), const struct cred *cred) { static const struct file_operations empty_fops = {}; int error; f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE; path_get(&f->f_path); f->f_inode = inode; f->f_mapping = inode->i_mapping; if (unlikely(f->f_flags & O_PATH)) { f->f_mode = FMODE_PATH; f->f_op = &empty_fops; return 0; } if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) { error = get_write_access(inode); if (unlikely(error)) goto cleanup_file; error = __mnt_want_write(f->f_path.mnt); if (unlikely(error)) { put_write_access(inode); goto cleanup_file; } f->f_mode |= FMODE_WRITER; } /* POSIX.1-2008/SUSv4 Section XSI 2.9.7 */ if (S_ISREG(inode->i_mode)) f->f_mode |= FMODE_ATOMIC_POS; f->f_op = fops_get(inode->i_fop); if (unlikely(WARN_ON(!f->f_op))) { error = -ENODEV; goto cleanup_all; } error = security_file_open(f, cred); if (error) goto cleanup_all; error = break_lease(inode, f->f_flags); if (error) goto cleanup_all; if (!open) open = f->f_op->open; if (open) { error = open(inode, f); if (error) goto cleanup_all; } if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) i_readcount_inc(inode); if ((f->f_mode & FMODE_READ) && likely(f->f_op->read || f->f_op->read_iter)) f->f_mode |= FMODE_CAN_READ; if ((f->f_mode & FMODE_WRITE) && likely(f->f_op->write || f->f_op->write_iter)) f->f_mode |= FMODE_CAN_WRITE; f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); return 0; cleanup_all: fops_put(f->f_op); if (f->f_mode & FMODE_WRITER) { put_write_access(inode); __mnt_drop_write(f->f_path.mnt); } cleanup_file: path_put(&f->f_path); f->f_path.mnt = NULL; f->f_path.dentry = NULL; f->f_inode = NULL; return error; } /** * finish_open - finish opening a file * @file: file pointer * @dentry: pointer to dentry * @open: open callback * @opened: state of open * * This can be used to finish opening a file passed to i_op->atomic_open(). * * If the open callback is set to NULL, then the standard f_op->open() * filesystem callback is substituted. * * NB: the dentry reference is _not_ consumed. If, for example, the dentry is * the return value of d_splice_alias(), then the caller needs to perform dput() * on it after finish_open(). * * On successful return @file is a fully instantiated open file. After this, if * an error occurs in ->atomic_open(), it needs to clean up with fput(). * * Returns zero on success or -errno if the open failed. */ int finish_open(struct file *file, struct dentry *dentry, int (*open)(struct inode *, struct file *), int *opened) { int error; BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */ file->f_path.dentry = dentry; error = do_dentry_open(file, d_backing_inode(dentry), open, current_cred()); if (!error) *opened |= FILE_OPENED; return error; } EXPORT_SYMBOL(finish_open); /** * finish_no_open - finish ->atomic_open() without opening the file * * @file: file pointer * @dentry: dentry or NULL (as returned from ->lookup()) * * This can be used to set the result of a successful lookup in ->atomic_open(). * * NB: unlike finish_open() this function does consume the dentry reference and * the caller need not dput() it. * * Returns "1" which must be the return value of ->atomic_open() after having * called this function. */ int finish_no_open(struct file *file, struct dentry *dentry) { file->f_path.dentry = dentry; return 1; } EXPORT_SYMBOL(finish_no_open); char *file_path(struct file *filp, char *buf, int buflen) { return d_path(&filp->f_path, buf, buflen); } EXPORT_SYMBOL(file_path); /** * vfs_open - open the file at the given path * @path: path to open * @file: newly allocated file with f_flag initialized * @cred: credentials to use */ int vfs_open(const struct path *path, struct file *file, const struct cred *cred) { struct inode *inode = vfs_select_inode(path->dentry, file->f_flags); if (IS_ERR(inode)) return PTR_ERR(inode); file->f_path = *path; return do_dentry_open(file, inode, NULL, cred); } struct file *dentry_open(const struct path *path, int flags, const struct cred *cred) { int error; struct file *f; validate_creds(cred); /* We must always pass in a valid mount pointer. */ BUG_ON(!path->mnt); f = get_empty_filp(); if (!IS_ERR(f)) { f->f_flags = flags; error = vfs_open(path, f, cred); if (!error) { /* from now on we need fput() to dispose of f */ error = open_check_o_direct(f); if (error) { fput(f); f = ERR_PTR(error); } } else { put_filp(f); f = ERR_PTR(error); } } return f; } EXPORT_SYMBOL(dentry_open); static inline int build_open_flags(int flags, umode_t mode, struct open_flags *op) { int lookup_flags = 0; int acc_mode; /* * Clear out all open flags we don't know about so that we don't report * them in fcntl(F_GETFD) or similar interfaces. */ flags &= VALID_OPEN_FLAGS; if (flags & (O_CREAT | __O_TMPFILE)) op->mode = (mode & S_IALLUGO) | S_IFREG; else op->mode = 0; /* Must never be set by userspace */ flags &= ~FMODE_NONOTIFY & ~O_CLOEXEC; /* * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only * check for O_DSYNC if the need any syncing at all we enforce it's * always set instead of having to deal with possibly weird behaviour * for malicious applications setting only __O_SYNC. */ if (flags & __O_SYNC) flags |= O_DSYNC; if (flags & __O_TMPFILE) { if ((flags & O_TMPFILE_MASK) != O_TMPFILE) return -EINVAL; acc_mode = MAY_OPEN | ACC_MODE(flags); if (!(acc_mode & MAY_WRITE)) return -EINVAL; } else if (flags & O_PATH) { /* * If we have O_PATH in the open flag. Then we * cannot have anything other than the below set of flags */ flags &= O_DIRECTORY | O_NOFOLLOW | O_PATH; acc_mode = 0; } else { acc_mode = MAY_OPEN | ACC_MODE(flags); } op->open_flag = flags; /* O_TRUNC implies we need access checks for write permissions */ if (flags & O_TRUNC) acc_mode |= MAY_WRITE; /* Allow the LSM permission hook to distinguish append access from general write access. */ if (flags & O_APPEND) acc_mode |= MAY_APPEND; op->acc_mode = acc_mode; op->intent = flags & O_PATH ? 0 : LOOKUP_OPEN; if (flags & O_CREAT) { op->intent |= LOOKUP_CREATE; if (flags & O_EXCL) op->intent |= LOOKUP_EXCL; } if (flags & O_DIRECTORY) lookup_flags |= LOOKUP_DIRECTORY; if (!(flags & O_NOFOLLOW)) lookup_flags |= LOOKUP_FOLLOW; op->lookup_flags = lookup_flags; return 0; } /** * file_open_name - open file and return file pointer * * @name: struct filename containing path to open * @flags: open flags as per the open(2) second argument * @mode: mode for the new file if O_CREAT is set, else ignored * * This is the helper to open a file from kernelspace if you really * have to. But in generally you should not do this, so please move * along, nothing to see here.. */ struct file *file_open_name(struct filename *name, int flags, umode_t mode) { struct open_flags op; int err = build_open_flags(flags, mode, &op); return err ? ERR_PTR(err) : do_filp_open(AT_FDCWD, name, &op); } /** * filp_open - open file and return file pointer * * @filename: path to open * @flags: open flags as per the open(2) second argument * @mode: mode for the new file if O_CREAT is set, else ignored * * This is the helper to open a file from kernelspace if you really * have to. But in generally you should not do this, so please move * along, nothing to see here.. */ struct file *filp_open(const char *filename, int flags, umode_t mode) { struct filename *name = getname_kernel(filename); struct file *file = ERR_CAST(name); if (!IS_ERR(name)) { file = file_open_name(name, flags, mode); putname(name); } return file; } EXPORT_SYMBOL(filp_open); struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt, const char *filename, int flags, umode_t mode) { struct open_flags op; int err = build_open_flags(flags, mode, &op); if (err) return ERR_PTR(err); return do_file_open_root(dentry, mnt, filename, &op); } EXPORT_SYMBOL(file_open_root); long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) { struct open_flags op; int fd = build_open_flags(flags, mode, &op); struct filename *tmp; if (fd) return fd; tmp = getname(filename); if (IS_ERR(tmp)) return PTR_ERR(tmp); fd = get_unused_fd_flags(flags); if (fd >= 0) { struct file *f = do_filp_open(dfd, tmp, &op); if (IS_ERR(f)) { put_unused_fd(fd); fd = PTR_ERR(f); } else { fsnotify_open(f); fd_install(fd, f); } } putname(tmp); return fd; } SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode) { if (force_o_largefile()) flags |= O_LARGEFILE; return do_sys_open(AT_FDCWD, filename, flags, mode); } SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, umode_t, mode) { if (force_o_largefile()) flags |= O_LARGEFILE; return do_sys_open(dfd, filename, flags, mode); } #ifndef __alpha__ /* * For backward compatibility? Maybe this should be moved * into arch/i386 instead? */ SYSCALL_DEFINE2(creat, const char __user *, pathname, umode_t, mode) { return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode); } #endif /* * "id" is the POSIX thread ID. We use the * files pointer for this.. */ int filp_close(struct file *filp, fl_owner_t id) { int retval = 0; if (!file_count(filp)) { printk(KERN_ERR "VFS: Close: file count is 0\n"); return 0; } if (filp->f_op->flush) retval = filp->f_op->flush(filp, id); if (likely(!(filp->f_mode & FMODE_PATH))) { dnotify_flush(filp, id); locks_remove_posix(filp, id); } fput(filp); return retval; } EXPORT_SYMBOL(filp_close); /* * Careful here! We test whether the file pointer is NULL before * releasing the fd. This ensures that one clone task can't release * an fd while another clone is opening it. */ SYSCALL_DEFINE1(close, unsigned int, fd) { int retval = __close_fd(current->files, fd); /* can't restart close syscall because file table entry was cleared */ if (unlikely(retval == -ERESTARTSYS || retval == -ERESTARTNOINTR || retval == -ERESTARTNOHAND || retval == -ERESTART_RESTARTBLOCK)) retval = -EINTR; return retval; } EXPORT_SYMBOL(sys_close); /* * This routine simulates a hangup on the tty, to arrange that users * are given clean terminals at login time. */ SYSCALL_DEFINE0(vhangup) { if (capable(CAP_SYS_TTY_CONFIG)) { tty_vhangup_self(); return 0; } return -EPERM; } /* * Called when an inode is about to be open. * We use this to disallow opening large files on 32bit systems if * the caller didn't specify O_LARGEFILE. On 64bit systems we force * on this flag in sys_open. */ int generic_file_open(struct inode * inode, struct file * filp) { if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) return -EOVERFLOW; return 0; } EXPORT_SYMBOL(generic_file_open); /* * This is used by subsystems that don't want seekable * file descriptors. The function is not supposed to ever fail, the only * reason it returns an 'int' and not 'void' is so that it can be plugged * directly into file_operations structure. */ int nonseekable_open(struct inode *inode, struct file *filp) { filp->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE); return 0; } EXPORT_SYMBOL(nonseekable_open); /* * stream_open is used by subsystems that want stream-like file descriptors. * Such file descriptors are not seekable and don't have notion of position * (file.f_pos is always 0). Contrary to file descriptors of other regular * files, .read() and .write() can run simultaneously. * * stream_open never fails and is marked to return int so that it could be * directly used as file_operations.open . */ int stream_open(struct inode *inode, struct file *filp) { filp->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE | FMODE_ATOMIC_POS); filp->f_mode |= FMODE_STREAM; return 0; } EXPORT_SYMBOL(stream_open); 问题1: 以上是mtk方案的一个sdk文件 open.c 使用以下,访问文件没有问题。 snprintf(cfgFile, MAX_LINE_LEN-1, "%s/dev_config.json", g_cfgPath); // cfgFile = /etc/xxxxxxxxxxxxxxxxxx/dev_config.json pFile = filp_open(cfgFile, O_RDONLY, 0); if (IS_ERR(pFile)) { PRINT_ERR("Fail to Open File %s", cfgFile); set_fs(origFs); return -1; } /* * linux/fs/open.c * * Copyright (C) 1991, 1992 Linus Torvalds */ #include <linux/string.h> #include <linux/mm.h> #include <linux/file.h> #include <linux/fdtable.h> #include <linux/fsnotify.h> #include <linux/module.h> #include <linux/tty.h> #include <linux/namei.h> #include <linux/backing-dev.h> #include <linux/capability.h> #include <linux/securebits.h> #include <linux/security.h> #include <linux/mount.h> #include <linux/fcntl.h> #include <linux/slab.h> #include <asm/uaccess.h> #include <linux/fs.h> #include <linux/personality.h> #include <linux/pagemap.h> #include <linux/syscalls.h> #include <linux/rcupdate.h> #include <linux/audit.h> #include <linux/falloc.h> #include <linux/fs_struct.h> #include <linux/ima.h> #include <linux/dnotify.h> #include <linux/compat.h> #include "internal.h" int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, struct file *filp) { int ret; struct iattr newattrs; /* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */ if (length < 0) return -EINVAL; newattrs.ia_size = length; newattrs.ia_valid = ATTR_SIZE | time_attrs; if (filp) { newattrs.ia_file = filp; newattrs.ia_valid |= ATTR_FILE; } /* Remove suid, sgid, and file capabilities on truncate too */ ret = dentry_needs_remove_privs(dentry); if (ret < 0) return ret; if (ret) newattrs.ia_valid |= ret | ATTR_FORCE; mutex_lock(&dentry->d_inode->i_mutex); /* Note any delegations or leases have already been broken: */ ret = notify_change(dentry, &newattrs, NULL); mutex_unlock(&dentry->d_inode->i_mutex); return ret; } long vfs_truncate(struct path *path, loff_t length) { struct inode *inode; long error; inode = path->dentry->d_inode; /* For directories it's -EISDIR, for other non-regulars - -EINVAL */ if (S_ISDIR(inode->i_mode)) return -EISDIR; if (!S_ISREG(inode->i_mode)) return -EINVAL; error = mnt_want_write(path->mnt); if (error) goto out; error = inode_permission(inode, MAY_WRITE); if (error) goto mnt_drop_write_and_out; error = -EPERM; if (IS_APPEND(inode)) goto mnt_drop_write_and_out; error = get_write_access(inode); if (error) goto mnt_drop_write_and_out; /* * Make sure that there are no leases. get_write_access() protects * against the truncate racing with a lease-granting setlease(). */ error = break_lease(inode, O_WRONLY); if (error) goto put_write_and_out; error = locks_verify_truncate(inode, NULL, length); if (!error) error = security_path_truncate(path); if (!error) error = do_truncate(path->dentry, length, 0, NULL); put_write_and_out: put_write_access(inode); mnt_drop_write_and_out: mnt_drop_write(path->mnt); out: return error; } EXPORT_SYMBOL_GPL(vfs_truncate); static long do_sys_truncate(const char __user *pathname, loff_t length) { unsigned int lookup_flags = LOOKUP_FOLLOW; struct path path; int error; if (length < 0) /* sorry, but loff_t says... */ return -EINVAL; retry: error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); if (!error) { error = vfs_truncate(&path, length); path_put(&path); } if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; goto retry; } return error; } SYSCALL_DEFINE2(truncate, const char __user *, path, long, length) { return do_sys_truncate(path, length); } #ifdef CONFIG_COMPAT COMPAT_SYSCALL_DEFINE2(truncate, const char __user *, path, compat_off_t, length) { return do_sys_truncate(path, length); } #endif static long do_sys_ftruncate(unsigned int fd, loff_t length, int small) { struct inode *inode; struct dentry *dentry; struct fd f; int error; error = -EINVAL; if (length < 0) goto out; error = -EBADF; f = fdget(fd); if (!f.file) goto out; /* explicitly opened as large or we are on 64-bit box */ if (f.file->f_flags & O_LARGEFILE) small = 0; dentry = f.file->f_path.dentry; inode = dentry->d_inode; error = -EINVAL; if (!S_ISREG(inode->i_mode) || !(f.file->f_mode & FMODE_WRITE)) goto out_putf; error = -EINVAL; /* Cannot ftruncate over 2^31 bytes without large file support */ if (small && length > MAX_NON_LFS) goto out_putf; error = -EPERM; if (IS_APPEND(inode)) goto out_putf; sb_start_write(inode->i_sb); error = locks_verify_truncate(inode, f.file, length); if (!error) error = security_path_truncate(&f.file->f_path); if (!error) error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, f.file); sb_end_write(inode->i_sb); out_putf: fdput(f); out: return error; } SYSCALL_DEFINE2(ftruncate, unsigned int, fd, unsigned long, length) { return do_sys_ftruncate(fd, length, 1); } #ifdef CONFIG_COMPAT COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_ulong_t, length) { return do_sys_ftruncate(fd, length, 1); } #endif /* LFS versions of truncate are only needed on 32 bit machines */ #if BITS_PER_LONG == 32 SYSCALL_DEFINE2(truncate64, const char __user *, path, loff_t, length) { return do_sys_truncate(path, length); } SYSCALL_DEFINE2(ftruncate64, unsigned int, fd, loff_t, length) { return do_sys_ftruncate(fd, length, 0); } #endif /* BITS_PER_LONG == 32 */ int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len) { struct inode *inode = file_inode(file); long ret; if (offset < 0 || len <= 0) return -EINVAL; /* Return error if mode is not supported */ if (mode & ~FALLOC_FL_SUPPORTED_MASK) return -EOPNOTSUPP; /* Punch hole and zero range are mutually exclusive */ if ((mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) == (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) return -EOPNOTSUPP; /* Punch hole must have keep size set */ if ((mode & FALLOC_FL_PUNCH_HOLE) && !(mode & FALLOC_FL_KEEP_SIZE)) return -EOPNOTSUPP; /* Collapse range should only be used exclusively. */ if ((mode & FALLOC_FL_COLLAPSE_RANGE) && (mode & ~FALLOC_FL_COLLAPSE_RANGE)) return -EINVAL; /* Insert range should only be used exclusively. */ if ((mode & FALLOC_FL_INSERT_RANGE) && (mode & ~FALLOC_FL_INSERT_RANGE)) return -EINVAL; if (!(file->f_mode & FMODE_WRITE)) return -EBADF; /* * We can only allow pure fallocate on append only files */ if ((mode & ~FALLOC_FL_KEEP_SIZE) && IS_APPEND(inode)) return -EPERM; if (IS_IMMUTABLE(inode)) return -EPERM; /* * We cannot allow any fallocate operation on an active swapfile */ if (IS_SWAPFILE(inode)) return -ETXTBSY; /* * Revalidate the write permissions, in case security policy has * changed since the files were opened. */ ret = security_file_permission(file, MAY_WRITE); if (ret) return ret; if (S_ISFIFO(inode->i_mode)) return -ESPIPE; /* * Let individual file system decide if it supports preallocation * for directories or not. */ if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) return -ENODEV; /* Check for wrap through zero too */ if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0)) return -EFBIG; if (!file->f_op->fallocate) return -EOPNOTSUPP; sb_start_write(inode->i_sb); ret = file->f_op->fallocate(file, mode, offset, len); /* * Create inotify and fanotify events. * * To keep the logic simple always create events if fallocate succeeds. * This implies that events are even created if the file size remains * unchanged, e.g. when using flag FALLOC_FL_KEEP_SIZE. */ if (ret == 0) fsnotify_modify(file); sb_end_write(inode->i_sb); return ret; } EXPORT_SYMBOL_GPL(vfs_fallocate); SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) { struct fd f = fdget(fd); int error = -EBADF; if (f.file) { error = vfs_fallocate(f.file, mode, offset, len); fdput(f); } return error; } /* * access() needs to use the real uid/gid, not the effective uid/gid. * We do this by temporarily clearing all FS-related capabilities and * switching the fsuid/fsgid around to the real ones. */ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) { const struct cred *old_cred; struct cred *override_cred; struct path path; struct inode *inode; int res; unsigned int lookup_flags = LOOKUP_FOLLOW; if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ return -EINVAL; override_cred = prepare_creds(); if (!override_cred) return -ENOMEM; override_cred->fsuid = override_cred->uid; override_cred->fsgid = override_cred->gid; if (!issecure(SECURE_NO_SETUID_FIXUP)) { /* Clear the capabilities if we switch to a non-root user */ kuid_t root_uid = make_kuid(override_cred->user_ns, 0); if (!uid_eq(override_cred->uid, root_uid)) cap_clear(override_cred->cap_effective); else override_cred->cap_effective = override_cred->cap_permitted; } old_cred = override_creds(override_cred); retry: res = user_path_at(dfd, filename, lookup_flags, &path); if (res) goto out; inode = d_backing_inode(path.dentry); if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) { /* * MAY_EXEC on regular files is denied if the fs is mounted * with the "noexec" flag. */ res = -EACCES; if (path_noexec(&path)) goto out_path_release; } res = inode_permission(inode, mode | MAY_ACCESS); /* SuS v2 requires we report a read only fs too */ if (res || !(mode & S_IWOTH) || special_file(inode->i_mode)) goto out_path_release; /* * This is a rare case where using __mnt_is_readonly() * is OK without a mnt_want/drop_write() pair. Since * no actual write to the fs is performed here, we do * not need to telegraph to that to anyone. * * By doing this, we accept that this access is * inherently racy and know that the fs may change * state before we even see this result. */ if (__mnt_is_readonly(path.mnt)) res = -EROFS; out_path_release: path_put(&path); if (retry_estale(res, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; goto retry; } out: revert_creds(old_cred); put_cred(override_cred); return res; } SYSCALL_DEFINE2(access, const char __user *, filename, int, mode) { return sys_faccessat(AT_FDCWD, filename, mode); } SYSCALL_DEFINE1(chdir, const char __user *, filename) { struct path path; int error; unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY; retry: error = user_path_at(AT_FDCWD, filename, lookup_flags, &path); if (error) goto out; error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR); if (error) goto dput_and_out; set_fs_pwd(current->fs, &path); dput_and_out: path_put(&path); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; goto retry; } out: return error; } SYSCALL_DEFINE1(fchdir, unsigned int, fd) { struct fd f = fdget_raw(fd); struct inode *inode; int error = -EBADF; error = -EBADF; if (!f.file) goto out; inode = file_inode(f.file); error = -ENOTDIR; if (!S_ISDIR(inode->i_mode)) goto out_putf; error = inode_permission(inode, MAY_EXEC | MAY_CHDIR); if (!error) set_fs_pwd(current->fs, &f.file->f_path); out_putf: fdput(f); out: return error; } SYSCALL_DEFINE1(chroot, const char __user *, filename) { struct path path; int error; unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY; retry: error = user_path_at(AT_FDCWD, filename, lookup_flags, &path); if (error) goto out; error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR); if (error) goto dput_and_out; error = -EPERM; if (!ns_capable(current_user_ns(), CAP_SYS_CHROOT)) goto dput_and_out; error = security_path_chroot(&path); if (error) goto dput_and_out; set_fs_root(current->fs, &path); error = 0; dput_and_out: path_put(&path); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; goto retry; } out: return error; } static int chmod_common(struct path *path, umode_t mode) { struct inode *inode = path->dentry->d_inode; struct inode *delegated_inode = NULL; struct iattr newattrs; int error; error = mnt_want_write(path->mnt); if (error) return error; retry_deleg: mutex_lock(&inode->i_mutex); error = security_path_chmod(path, mode); if (error) goto out_unlock; newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; error = notify_change(path->dentry, &newattrs, &delegated_inode); out_unlock: mutex_unlock(&inode->i_mutex); if (delegated_inode) { error = break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; } mnt_drop_write(path->mnt); return error; } SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode) { struct fd f = fdget(fd); int err = -EBADF; if (f.file) { audit_file(f.file); err = chmod_common(&f.file->f_path, mode); fdput(f); } return err; } SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode) { struct path path; int error; unsigned int lookup_flags = LOOKUP_FOLLOW; retry: error = user_path_at(dfd, filename, lookup_flags, &path); if (!error) { error = chmod_common(&path, mode); path_put(&path); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; goto retry; } } return error; } SYSCALL_DEFINE2(chmod, const char __user *, filename, umode_t, mode) { return sys_fchmodat(AT_FDCWD, filename, mode); } static int chown_common(struct path *path, uid_t user, gid_t group) { struct inode *inode = path->dentry->d_inode; struct inode *delegated_inode = NULL; int error; struct iattr newattrs; kuid_t uid; kgid_t gid; uid = make_kuid(current_user_ns(), user); gid = make_kgid(current_user_ns(), group); retry_deleg: newattrs.ia_valid = ATTR_CTIME; if (user != (uid_t) -1) { if (!uid_valid(uid)) return -EINVAL; newattrs.ia_valid |= ATTR_UID; newattrs.ia_uid = uid; } if (group != (gid_t) -1) { if (!gid_valid(gid)) return -EINVAL; newattrs.ia_valid |= ATTR_GID; newattrs.ia_gid = gid; } if (!S_ISDIR(inode->i_mode)) newattrs.ia_valid |= ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; mutex_lock(&inode->i_mutex); error = security_path_chown(path, uid, gid); if (!error) error = notify_change(path->dentry, &newattrs, &delegated_inode); mutex_unlock(&inode->i_mutex); if (delegated_inode) { error = break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; } return error; } SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user, gid_t, group, int, flag) { struct path path; int error = -EINVAL; int lookup_flags; if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0) goto out; lookup_flags = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW; if (flag & AT_EMPTY_PATH) lookup_flags |= LOOKUP_EMPTY; retry: error = user_path_at(dfd, filename, lookup_flags, &path); if (error) goto out; error = mnt_want_write(path.mnt); if (error) goto out_release; error = chown_common(&path, user, group); mnt_drop_write(path.mnt); out_release: path_put(&path); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; goto retry; } out: return error; } SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group) { return sys_fchownat(AT_FDCWD, filename, user, group, 0); } SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group) { return sys_fchownat(AT_FDCWD, filename, user, group, AT_SYMLINK_NOFOLLOW); } SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) { struct fd f = fdget(fd); int error = -EBADF; if (!f.file) goto out; error = mnt_want_write_file(f.file); if (error) goto out_fput; audit_file(f.file); error = chown_common(&f.file->f_path, user, group); mnt_drop_write_file(f.file); out_fput: fdput(f); out: return error; } int open_check_o_direct(struct file *f) { /* NB: we're sure to have correct a_ops only after f_op->open */ if (f->f_flags & O_DIRECT) { #ifdef CONFIG_DIRECT_IO if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO) #endif return -EINVAL; } return 0; } static int do_dentry_open(struct file *f, struct inode *inode, int (*open)(struct inode *, struct file *), const struct cred *cred) { static const struct file_operations empty_fops = {}; int error; f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE; path_get(&f->f_path); f->f_inode = inode; f->f_mapping = inode->i_mapping; if (unlikely(f->f_flags & O_PATH)) { f->f_mode = FMODE_PATH; f->f_op = &empty_fops; return 0; } if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) { error = get_write_access(inode); if (unlikely(error)) goto cleanup_file; error = __mnt_want_write(f->f_path.mnt); if (unlikely(error)) { put_write_access(inode); goto cleanup_file; } f->f_mode |= FMODE_WRITER; } /* POSIX.1-2008/SUSv4 Section XSI 2.9.7 */ if (S_ISREG(inode->i_mode)) f->f_mode |= FMODE_ATOMIC_POS; f->f_op = fops_get(inode->i_fop); if (unlikely(WARN_ON(!f->f_op))) { error = -ENODEV; goto cleanup_all; } error = security_file_open(f, cred); if (error) goto cleanup_all; error = break_lease(inode, f->f_flags); if (error) goto cleanup_all; if (!open) open = f->f_op->open; if (open) { error = open(inode, f); if (error) goto cleanup_all; } if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) i_readcount_inc(inode); if ((f->f_mode & FMODE_READ) && likely(f->f_op->read || f->f_op->read_iter)) f->f_mode |= FMODE_CAN_READ; if ((f->f_mode & FMODE_WRITE) && likely(f->f_op->write || f->f_op->write_iter)) f->f_mode |= FMODE_CAN_WRITE; f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); return 0; cleanup_all: fops_put(f->f_op); if (f->f_mode & FMODE_WRITER) { put_write_access(inode); __mnt_drop_write(f->f_path.mnt); } cleanup_file: path_put(&f->f_path); f->f_path.mnt = NULL; f->f_path.dentry = NULL; f->f_inode = NULL; return error; } /** * finish_open - finish opening a file * @file: file pointer * @dentry: pointer to dentry * @open: open callback * @opened: state of open * * This can be used to finish opening a file passed to i_op->atomic_open(). * * If the open callback is set to NULL, then the standard f_op->open() * filesystem callback is substituted. * * NB: the dentry reference is _not_ consumed. If, for example, the dentry is * the return value of d_splice_alias(), then the caller needs to perform dput() * on it after finish_open(). * * On successful return @file is a fully instantiated open file. After this, if * an error occurs in ->atomic_open(), it needs to clean up with fput(). * * Returns zero on success or -errno if the open failed. */ int finish_open(struct file *file, struct dentry *dentry, int (*open)(struct inode *, struct file *), int *opened) { int error; BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */ file->f_path.dentry = dentry; error = do_dentry_open(file, d_backing_inode(dentry), open, current_cred()); if (!error) *opened |= FILE_OPENED; return error; } EXPORT_SYMBOL(finish_open); /** * finish_no_open - finish ->atomic_open() without opening the file * * @file: file pointer * @dentry: dentry or NULL (as returned from ->lookup()) * * This can be used to set the result of a successful lookup in ->atomic_open(). * * NB: unlike finish_open() this function does consume the dentry reference and * the caller need not dput() it. * * Returns "1" which must be the return value of ->atomic_open() after having * called this function. */ int finish_no_open(struct file *file, struct dentry *dentry) { file->f_path.dentry = dentry; return 1; } EXPORT_SYMBOL(finish_no_open); char *file_path(struct file *filp, char *buf, int buflen) { return d_path(&filp->f_path, buf, buflen); } EXPORT_SYMBOL(file_path); /** * vfs_open - open the file at the given path * @path: path to open * @file: newly allocated file with f_flag initialized * @cred: credentials to use */ int vfs_open(const struct path *path, struct file *file, const struct cred *cred) { struct inode *inode = vfs_select_inode(path->dentry, file->f_flags); if (IS_ERR(inode)) return PTR_ERR(inode); file->f_path = *path; return do_dentry_open(file, inode, NULL, cred); } struct file *dentry_open(const struct path *path, int flags, const struct cred *cred) { int error; struct file *f; validate_creds(cred); /* We must always pass in a valid mount pointer. */ BUG_ON(!path->mnt); f = get_empty_filp(); if (!IS_ERR(f)) { f->f_flags = flags; error = vfs_open(path, f, cred); if (!error) { /* from now on we need fput() to dispose of f */ error = open_check_o_direct(f); if (error) { fput(f); f = ERR_PTR(error); } } else { put_filp(f); f = ERR_PTR(error); } } return f; } EXPORT_SYMBOL(dentry_open); static inline int build_open_flags(int flags, umode_t mode, struct open_flags *op) { int lookup_flags = 0; int acc_mode; if (flags & (O_CREAT | __O_TMPFILE)) op->mode = (mode & S_IALLUGO) | S_IFREG; else op->mode = 0; /* Must never be set by userspace */ flags &= ~FMODE_NONOTIFY & ~O_CLOEXEC; /* * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only * check for O_DSYNC if the need any syncing at all we enforce it's * always set instead of having to deal with possibly weird behaviour * for malicious applications setting only __O_SYNC. */ if (flags & __O_SYNC) flags |= O_DSYNC; if (flags & __O_TMPFILE) { if ((flags & O_TMPFILE_MASK) != O_TMPFILE) return -EINVAL; acc_mode = MAY_OPEN | ACC_MODE(flags); if (!(acc_mode & MAY_WRITE)) return -EINVAL; } else if (flags & O_PATH) { /* * If we have O_PATH in the open flag. Then we * cannot have anything other than the below set of flags */ flags &= O_DIRECTORY | O_NOFOLLOW | O_PATH; acc_mode = 0; } else { acc_mode = MAY_OPEN | ACC_MODE(flags); } op->open_flag = flags; /* O_TRUNC implies we need access checks for write permissions */ if (flags & O_TRUNC) acc_mode |= MAY_WRITE; /* Allow the LSM permission hook to distinguish append access from general write access. */ if (flags & O_APPEND) acc_mode |= MAY_APPEND; op->acc_mode = acc_mode; op->intent = flags & O_PATH ? 0 : LOOKUP_OPEN; if (flags & O_CREAT) { op->intent |= LOOKUP_CREATE; if (flags & O_EXCL) op->intent |= LOOKUP_EXCL; } if (flags & O_DIRECTORY) lookup_flags |= LOOKUP_DIRECTORY; if (!(flags & O_NOFOLLOW)) lookup_flags |= LOOKUP_FOLLOW; op->lookup_flags = lookup_flags; return 0; } /** * file_open_name - open file and return file pointer * * @name: struct filename containing path to open * @flags: open flags as per the open(2) second argument * @mode: mode for the new file if O_CREAT is set, else ignored * * This is the helper to open a file from kernelspace if you really * have to. But in generally you should not do this, so please move * along, nothing to see here.. */ struct file *file_open_name(struct filename *name, int flags, umode_t mode) { struct open_flags op; int err = build_open_flags(flags, mode, &op); return err ? ERR_PTR(err) : do_filp_open(AT_FDCWD, name, &op); } /** * filp_open - open file and return file pointer * * @filename: path to open * @flags: open flags as per the open(2) second argument * @mode: mode for the new file if O_CREAT is set, else ignored * * This is the helper to open a file from kernelspace if you really * have to. But in generally you should not do this, so please move * along, nothing to see here.. */ struct file *filp_open(const char *filename, int flags, umode_t mode) { struct filename *name = getname_kernel(filename); struct file *file = ERR_CAST(name); if (!IS_ERR(name)) { file = file_open_name(name, flags, mode); putname(name); } return file; } EXPORT_SYMBOL(filp_open); struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt, const char *filename, int flags, umode_t mode) { struct open_flags op; int err = build_open_flags(flags, mode, &op); if (err) return ERR_PTR(err); return do_file_open_root(dentry, mnt, filename, &op); } EXPORT_SYMBOL(file_open_root); long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) { struct open_flags op; int fd = build_open_flags(flags, mode, &op); struct filename *tmp; if (fd) return fd; tmp = getname(filename); if (IS_ERR(tmp)) return PTR_ERR(tmp); fd = get_unused_fd_flags(flags); if (fd >= 0) { struct file *f = do_filp_open(dfd, tmp, &op); if (IS_ERR(f)) { put_unused_fd(fd); fd = PTR_ERR(f); } else { fsnotify_open(f); fd_install(fd, f); } } putname(tmp); return fd; } SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode) { if (force_o_largefile()) flags |= O_LARGEFILE; return do_sys_open(AT_FDCWD, filename, flags, mode); } SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, umode_t, mode) { if (force_o_largefile()) flags |= O_LARGEFILE; return do_sys_open(dfd, filename, flags, mode); } #ifndef __alpha__ /* * For backward compatibility? Maybe this should be moved * into arch/i386 instead? */ SYSCALL_DEFINE2(creat, const char __user *, pathname, umode_t, mode) { return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode); } #endif /* * "id" is the POSIX thread ID. We use the * files pointer for this.. */ int filp_close(struct file *filp, fl_owner_t id) { int retval = 0; if (!file_count(filp)) { printk(KERN_ERR "VFS: Close: file count is 0\n"); return 0; } if (filp->f_op->flush) retval = filp->f_op->flush(filp, id); if (likely(!(filp->f_mode & FMODE_PATH))) { dnotify_flush(filp, id); locks_remove_posix(filp, id); } fput(filp); return retval; } EXPORT_SYMBOL(filp_close); /* * Careful here! We test whether the file pointer is NULL before * releasing the fd. This ensures that one clone task can't release * an fd while another clone is opening it. */ SYSCALL_DEFINE1(close, unsigned int, fd) { int retval = __close_fd(current->files, fd); /* can't restart close syscall because file table entry was cleared */ if (unlikely(retval == -ERESTARTSYS || retval == -ERESTARTNOINTR || retval == -ERESTARTNOHAND || retval == -ERESTART_RESTARTBLOCK)) retval = -EINTR; return retval; } EXPORT_SYMBOL(sys_close); /* * This routine simulates a hangup on the tty, to arrange that users * are given clean terminals at login time. */ SYSCALL_DEFINE0(vhangup) { if (capable(CAP_SYS_TTY_CONFIG)) { tty_vhangup_self(); return 0; } return -EPERM; } /* * Called when an inode is about to be open. * We use this to disallow opening large files on 32bit systems if * the caller didn't specify O_LARGEFILE. On 64bit systems we force * on this flag in sys_open. */ int generic_file_open(struct inode * inode, struct file * filp) { if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) return -EOVERFLOW; return 0; } EXPORT_SYMBOL(generic_file_open); /* * This is used by subsystems that don't want seekable * file descriptors. The function is not supposed to ever fail, the only * reason it returns an 'int' and not 'void' is so that it can be plugged * directly into file_operations structure. */ int nonseekable_open(struct inode *inode, struct file *filp) { filp->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE); return 0; } EXPORT_SYMBOL(nonseekable_open); 问题1: 以上是qca方案的一个sdk文件 open.c 使用以下,访问文件会报错:[ 15.669739] [Error _btn_parse_conf:1007] Fail to Open File /etc/xxxxxxxxxxxxxxxxxx/dev_config.json snprintf(cfgFile, MAX_LINE_LEN-1, "%s/dev_config.json", g_cfgPath); // cfgFile = /etc/xxxxxxxxxxxxxxxxxx/dev_config.json pFile = filp_open(cfgFile, O_RDONLY, 0); if (IS_ERR(pFile)) { PRINT_ERR("Fail to Open File %s", cfgFile); set_fs(origFs); return -1; } 问题1:告诉我哪里出问题了
最新发布
12-19
<think>我们收到一个编译错误:fatal error: asm/ptrace_offsets.h: No such file or directory 这个错误通常发生在尝试编译使用ptrace相关功能的程序时,系统缺少必要的头文件。 分析: 1.文件路径:`asm/ptrace_offsets.h` 通常属于内核头文件的一部分,用于提供ptrace系统调用所需的寄存器偏移量定义。 2. 常见原因: - 没有安装对应架构的内核头文件。 - 交叉编译时,未正确指定目标平台的头文件路径。 - 文件路径在不同发行版中可能不同(如asm/可能对应arch/<arch>/include/asm/)。 解决方案: 1. 安装内核头文件: 对于Debian/Ubuntu系统: sudo apt-get install linux-headers-$(uname -r) 对于Arch Linux: sudo pacman -S linux-headers 对于RHEL/CentOS: sudo yum install kernel-devel 2. 如果是交叉编译(例如aarch64): 需要安装目标平台的头文件: sudo apt-get install linux-headers-<target-arch> 例如aarch64: sudo apt-get install linux-headers-arm64 3. 检查头文件位置: 安装后,检查头文件是否存在: find /usr -name ptrace_offsets.h 如果文件路径不在标准包含路径,需要在编译时通过`-I`选项指定。 4. 如果问题持续,考虑以下可能: - 内核版本与头文件版本不匹配:确保安装的头文件版本与运行的内核版本一致。 - 文件命名差异:有些系统可能使用不同的文件名或路径。 5. 临时解决方案(不推荐): 如果不需要ptrace功能,可以在代码中移除相关引用。但通常不现实。 注意:由于不同发行版的文件结构不同,可能需要查找具体位置并创建符号链接,但最好通过包管理解决。 §§相关问题§§ 1. 如何检查当前系统安装的内核头文件版本是否与运行内核匹配?2. 在交叉编译环境中,如何正确安装和配置目标平台的内核头文件?3. 如果系统不支持安装标准内核头文件,如何手动获取并配置所需的ptrace_offsets.h文件?4. 如何为不同的Linux发行版(如Ubuntu、CentOS、Arch)安装内核头文件?5. 编译时出现头文件缺失错误,如何快速确定该头文件属于哪个软件包? </think>您好!编译报错 `fatal error: asm/ptrace_offsets.h: No such file or directory` 表明编译器在尝试包含 `asm/ptrace_offsets.h` 头文件时失败,该文件通常与Linux内核开发和系统级调试相关。以下是详细分析和解决方案: ### 错误原因: 1. **内核头文件缺失**: `ptrace_offsets.h` 是Linux内核开发专用头文件,用于定义ptrace系统调用的寄存器偏移量。大多数常规系统不会默认安装这些头文件。 2. **平台架构不匹配**: 头文件路径中的 `asm/` 是架构相关目录(实际指向 `arch/<architecture>/include/asm/`)。如果目标架构(如ARM/AArch64)与当前系统不匹配,会导致文件不存在。 3. **开发环境不完整**: 该错误常见于需要编译内核模块、系统工具(如strace、gdb)或嵌入式开发时,缺少必要的开发包。 ### 解决方案: 1. **安装内核头文件包**: 根据Linux发行版安装对应包: ```bash # Ubuntu/Debian sudo apt-get install linux-headers-$(uname -r) # RHEL/CentOS sudo yum install kernel-devel-$(uname -r) # Arch Linux sudo pacman -S linux-headers ``` 2. **解决架构路径问题**: 创建符号链接修正路径(示例为x86_64架构): ```bash sudo ln -s /usr/src/linux-headers-$(uname -r)/arch/x86/include/uapi/asm /usr/include/asm ``` 3. **交叉编译环境配置**: 如果是交叉编译(如ARM平台): ```bash # 安装目标架构头文件 sudo apt-get install linux-headers-arm64 # 指定包含路径 export C_INCLUDE_PATH=/usr/aarch64-linux-gnu/include ``` 4. **源码编译安装**: 如果包管理器不可用: ```bash wget https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.10.tar.xz tar -xf linux-5.10.tar.xz sudo cp -r linux-5.10/arch/x86/include/uapi/asm /usr/include/ ``` 5. **代码修改(临时方案)**: 如果无需实际ptrace功能,在源码中注释包含声明: ```c // #include <asm/ptrace_offsets.h> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值